package com.xhwl.data.service.impl;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netflix.discovery.converters.Auto;
import com.xhwl.common.dto.cent.sdata.AccountDetailDTO;
import com.xhwl.common.dto.cent.sdata.OrgNodeDTO;
import com.xhwl.common.dto.cent.sdata.OrganizationDTO;
import com.xhwl.common.enums.LogOperationTypeEnum;
import com.xhwl.common.enums.LogicalEnum;
import com.xhwl.common.enums.ModuleTypeEnum;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.config.IndustryEnum;
import com.xhwl.common.enums.config.PermissionTypeEnum;
import com.xhwl.common.enums.config.RoleTypeEnum;
import com.xhwl.common.enums.sdata.EnterpriseTypeEnum;
import com.xhwl.common.enums.sdata.OrganizationViewStatusEnum;
import com.xhwl.common.enums.sdata.OrganizationVisibleObjectTypeEnum;
import com.xhwl.common.enums.space.ViewType;
import com.xhwl.common.exception.BusinessException;
import com.xhwl.common.exception.DataException;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffDTO;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffOrganization;
import com.xhwl.common.pojo.cent.sdata.space.OrganizationImport;
import com.xhwl.common.query.cent.sdata.*;
import com.xhwl.common.utils.ChkUtil;
import com.xhwl.common.utils.ThreadLocalUtil;
import com.xhwl.data.dao.*;
import com.xhwl.data.dao.personal.IStaffOrganizationDao;
import com.xhwl.data.mq.producer.OrganizationProducer;
import com.xhwl.data.pojo.dto.personal.OrgStaffTreeDTO;
import com.xhwl.data.pojo.dto.personal.OrgStaffTreeQueryDTO;
import com.xhwl.data.pojo.organization.OrganizationExcelDTO;
import com.xhwl.data.pojo.organization.OrganizationExcelError;
import com.xhwl.data.pojo.organization.OrganizationImportHandler;
import com.xhwl.data.service.*;
import com.xhwl.data.service.personal.IStaffService;
import com.xhwl.data.util.CodeGenerator;
import com.xhwl.data.util.excel.ExcelTypeEnum;
import com.xhwl.data.util.excel.FileNameUtil;
import com.xhwl.starter.log.LogTemplate;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotNull;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.util.List;

/**
 * @description: 组织管理
 * @author: lianghz
 * @create: 2020-11-25
 **/
@Service
public class OrganizationServiceImpl extends ServiceImpl<IOrganizationDao, Organization> implements IOrganizationService {

    private static final Logger log = LoggerFactory.getLogger(OrganizationServiceImpl.class);

    @Autowired
    private IOrganizationDao organizationDao;
    @Autowired
    private IRoleService roleService;
    @Autowired
    private IAccountOrganizationDao accountOrganizationDao;
    @Autowired
    private IProjectDao projectDao;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private IAccountProjectDao accountProjectDao;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private IBuildingService buildingService;
    @Autowired
    private IFloorService floorService;
    @Autowired
    private IPublicAreaService publicAreaService;
    @Autowired
    private IRoomService roomService;
    @Autowired
    private IEnterpriseDao enterpriseDao;
    @Autowired
    LogTemplate logTemplate;
    @Autowired
    IStaffOrganizationDao staffOrganizationDao;
    @Autowired
    private IOrganizationTypeService organizationTypeService;
    @Autowired
    private IOrganizationVisibilityService organizationVisibilityService;
    @Autowired
    private IOrganizationManagerService organizationManagerService;
    @Autowired
    private IStaffService staffService;

    @Autowired
    private OrganizationProducer organizationProducer;

    @Autowired
    private IAccountProjectService accountProjectService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IPermissionService permissionService;

    @Autowired
    private IProjectPermissionService projectPermissionService;

    @Autowired
    private IRolePermissionService rolePermissionService;

    @Autowired
    private IEnterpriseService enterpriseService;

    @Autowired
    private IEnterpriseProjectService enterpriseProjectService;
    @Autowired
    private IOrganizationSpaceService organizationSpaceService;
    @Autowired
    private ICustomOrganizationTypeService customOrganizationTypeService;

    @Autowired
    private OrganizationImportHandler organizationImportHandler;

    @Autowired
    private IOrganizationImportService organizationImportService;

    @Autowired
    private IOrganizationExcelErrorService organizationExcelErrorService;

    @Autowired
    private IOrganizationTypeDao organizationTypeDao;

    @Autowired


    private ISpaceFunctionTypeService spaceFunctionTypeService;

    @Autowired
    private IIndustryService industryService;

    @Autowired
    private ISceneService sceneService;

    @Autowired
    private IEnterpriseSpaceService enterpriseSpaceService;

    @Override
    public List<Integer> getOrgIdsList(List<Integer> orgIds) {
        if (orgIds.isEmpty()){
            return null;
        }
        List<Organization> organizationList = child(new OrganizationQuery().withIds(orgIds));
        if (organizationList.isEmpty()){
            return null;
        }
        return organizationList.stream().map(Organization::getId).collect(Collectors.toList());
    }

    /**
     * 检测到项目管理员，是否选择了企业层级组织
     *
     * @param account
     * @param organizationId
     * @return
     */
    @Override
    public Boolean canSelect(Account account, Integer organizationId) {
        Integer operateAccountId = account.getId();
        boolean projectManager = roleService.isProjectManager(operateAccountId);
        if (!projectManager) {
            return true;
        }
        Organization organization = getById(organizationId);
        if (null == organization) {
            throw new DataException("不存在该组织,操作失败");
        }
        Integer type = organization.getType();
        //如果是企业级角色
        if (OrganizationTypeEnum.ENTERPRISE.id.intValue() == type) {
            log.info("检测到项目管理员，选择了企业层级组织，已拦截,operateAccountId={},organizationId={}", operateAccountId, organizationId);
            return false;
        }
        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultJson create(List<Organization> organizationList) {
        if (null == organizationList || organizationList.isEmpty()) {
            log.warn("批量创建组织失败，入参为空");
            return ResultJson.fail("参数错误");
        }
        if (!nameCheck(organizationList)) {
            log.warn("传入的集合中存在名称重复");
            return ResultJson.fail("名称重复");
        }
        List<Organization> createList = new ArrayList<>();
        List<Integer> collect = organizationList.stream().filter(o -> null != o.getParentId()).map(o -> o.getParentId()).distinct().collect(Collectors.toList());
        if (collect.isEmpty()) {
            return ResultJson.fail("缺少父级信息");
        }
        List<Organization> parents = organizationDao.selectBatchIds(collect);
        if (parents.isEmpty()) {
            return ResultJson.fail("缺少父级信息");
        }
        Map<Integer, Organization> organizationMap = parents.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key2));

        for (Organization organization : organizationList) {
            ResultJson filter = batchFilter(organization, organizationMap.get(organization.getParentId()));
            if (filter.getState()) {
                createList.add(organization);

            } else {
                log.warn("批量创建组织失败，{}", filter.getMessage());
            }
        }
        this.saveBatch(createList);

        List<String> nameList = createList.stream().map(e -> e.getName()).collect(Collectors.toList());
        String orgNames = "";
        if (!CollectionUtils.isEmpty(nameList)) {
            orgNames = String.join("、", nameList);
        }
        if (CollectionUtils.isEmpty(createList)) {
            return ResultJson.success();
        }
        Organization organization = createList.get(0);
        //记录日志
        organizationLogRecord(null, LogOperationTypeEnum.CREATE, "新增组织" + "【" + orgNames + "】", organization);
        return ResultJson.success("创建成功", createList);
    }

    /**
     * 组织批量导入
     * @param file
     * @param industryId
     * @return
     */

    @Override
    public ResultJson createByImport(MultipartFile file,Short industryId,Integer enterpriseId,Account account){
        try {
            //校验文件合法性
            String originalFilename = file.getOriginalFilename();
            String fileNameSuffix = FileNameUtil.getFileNameSuffix(originalFilename);
            if (!(ExcelTypeEnum.XLS.getValue().equals(fileNameSuffix) || ExcelTypeEnum.XLSX.getValue().equals(fileNameSuffix))) {
                return ResultJson.fail("文件格式错误，仅支持导入xls/xlsx文件");
            }
            // 获取文件的输入流
            InputStream inputStream = file.getInputStream();

            try {
                organizationImportHandler.importData(inputStream, industryId, originalFilename,enterpriseId,account);
                return ResultJson.success();
            } catch (Exception e) {
                log.info("批量导入数据失败");
                e.printStackTrace();
            }
            // 处理完文件后记得关闭输入流
            inputStream.close();
        } catch (IOException e) {
            // 处理异常情况
            log.info("批量导入文件转换成输入流失败");
            e.printStackTrace();
        }
        return ResultJson.fail("批量导入数据失败");
    }

    /**
     * 批量导出错误数据
     */
    @Override
    public void exportErrorByFileId(HttpServletResponse response, @RequestParam String fileId){
        QueryWrapper<OrganizationImport> organizationImportQueryWrapper = new QueryWrapper<>();
        organizationImportQueryWrapper.eq("file_id",fileId);
        List<OrganizationImport> organizationImports = organizationImportService.list(organizationImportQueryWrapper);
        if (organizationImports.isEmpty()){
            throw new BusinessException("导出组织错误文件不存在");
        }

        QueryWrapper<OrganizationExcelError> organizationExcelErrorQueryWrapper = new QueryWrapper<>();
        organizationExcelErrorQueryWrapper.eq("file_id",fileId);
        List<OrganizationExcelError> organizationExcelErrors = organizationExcelErrorService.list(organizationExcelErrorQueryWrapper);
        List<OrganizationExcelDTO> exportErrorOrgLists = new ArrayList<>();
        for (OrganizationExcelError organizationExcelError : organizationExcelErrors) {
            String obj = organizationExcelError.getObj();
            OrganizationExcelDTO organizationExcelDTO = JSON.parseObject(obj, OrganizationExcelDTO.class);
            organizationExcelDTO.setReason(organizationExcelError.getReason());
            exportErrorOrgLists.add(organizationExcelDTO);
        }

        try {
            String[] headers = {"*企业编码", "*企业名称", "*上级组织编码", "*上级组织名称", "组织编码",
                    "*组织名称", "*组织类型名称","错误提示"};
            String exportName = "batch-error";
                writeToExcel(exportErrorOrgLists,fileId,response,headers,exportName);
            log.info("组织错误数据导出成功");
        } catch (Exception e) {
            e.printStackTrace();
            log.warn("组织错误数据导出失败");
        }
    }

    /**
     * 批量导出组织
     * @param response
     * @param keywords
     * @return
     */
    @Override
    public void exportBatchOrg(String keywords,Integer enterpriseId,HttpServletResponse response){

        if (enterpriseId == null){
            throw new DataException("缺少企业id，数据异常");
        }

        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        if (null != keywords && !keywords.isEmpty()){
            organizationQueryWrapper.like("name",keywords);
        }
        organizationQueryWrapper.eq("is_deleted",0);
        organizationQueryWrapper.eq("enterprise_id",enterpriseId);
        organizationQueryWrapper.orderByDesc("created_at");
        organizationQueryWrapper.eq("type",4);
        List<Organization> organizationList = this.list(organizationQueryWrapper);
        if (organizationList.isEmpty()){
            throw new BusinessException("导出组织为空数据");
        }
        List<OrganizationExcelDTO> organizationExcelDTOList = new ArrayList<>();

        //如果查询条件不为空，则先上查询,直到没有上级组织。
        if (null != keywords && !keywords.isEmpty()){
            for (Organization organizationExcel : organizationList){
                List<Organization> organizations = new ArrayList<>();
                List<Organization> organizationByLevel = getOrganizationByLevel(organizationExcel.getId(), organizationExcel.getLevel(), organizations);

                for (int i = 0; i < organizationByLevel.size(); i++) {
                    OrganizationExcelDTO organizationExcel1 = getOrganizationExcel(organizationByLevel.get(i));
                    organizationExcelDTOList.add(organizationExcel1);
                }
            }
        }else {
            for (Organization organizationExcel : organizationList){
                OrganizationExcelDTO organizationExcel1 = getOrganizationExcel(organizationExcel);
                organizationExcelDTOList.add(organizationExcel1);
            }
        }
        String fileName = UUID.randomUUID().toString().replaceAll("-", "");
        try {
            String[] headers = {"*企业编码", "*企业名称", "*上级组织编码", "*上级组织名称", "组织编码",
                    "*组织名称", "*组织类型名称", "组织负责人手机号"};
            String exportName = "batch-export";
            writeToExcel(organizationExcelDTOList,fileName,response,headers,exportName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 组织管理批量导入模板
     * @param response
     */
    @Override
    public void  exportOrganizationTemp(Integer enterpriseId, HttpServletResponse response) throws IOException{
        String fileName = "组织管理批量导入模板";
        String basePath = ResourceUtils.getURL("classpath:").getPath();
        String filePath = basePath + "template/" + fileName + ".xlsx";
        Enterprise enterprise = enterpriseService.findById(enterpriseId);
        QueryWrapper<CustomOrganizationType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("enterprise_id",enterpriseId);
        List<CustomOrganizationType> types = customOrganizationTypeService.list(queryWrapper);
        List<String> typeNames = types.stream().map(CustomOrganizationType::getName).collect(Collectors.toList());
        //查询企业下所有组织信息
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("enterprise_id",enterpriseId);
        organizationQueryWrapper.in("type",OrganizationTypeEnum.ORG.id,OrganizationTypeEnum.ENTERPRISE.id);
        List<Organization> organizationList = this.list(organizationQueryWrapper);

        if (null == enterprise){
            throw new DataException("企业不存在,数据异常");
        }
        if (CollectionUtils.isEmpty(typeNames)){
            throw new DataException("组织类型不存在,数据异常");
        }
        if (filePath != null){
            File file = new File(filePath);
            response.setHeader("content-type", "application/octet-stream");
            response.setContentType("application/octet-stream");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");
            response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
            FileInputStream fis = null;
            BufferedInputStream bis = null;
            try {
                fis = new FileInputStream(file);
                Workbook workbook = null;
                try {
                    workbook = new XSSFWorkbook(fis);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                assert workbook != null;
                Sheet sheet = workbook.getSheetAt(0);
                CellStyle cellStyle = workbook.createCellStyle();
                cellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
                cellStyle.setAlignment(HorizontalAlignment.CENTER);
                Font font = workbook.createFont();
                cellStyle.setFont(font);
                // 获取第二行第一个单元格的样式
                CellStyle templateCellStyle = sheet.getRow(1).getCell(0).getCellStyle();
                Font fontRow = workbook.createFont();
                fontRow.setFontName("宋体");
                fontRow.setFontHeightInPoints((short) 10); // 设置字体大小为10号

                //填充企业编码、名称、上级组织编码、上级组织名称
                int sizeRow = organizationList.size();
                String enterpriseCode = enterprise.getCode();
                String enterpriseName = enterprise.getName();
                for (int i = 2; i < sizeRow+2; i++) {
                    Row row = sheet.createRow(i);
                    // 复制样式并应用到每一行的单元格
                    CellStyle rowCellStyle = workbook.createCellStyle();
                    rowCellStyle.cloneStyleFrom(templateCellStyle); // 复制样式
                    rowCellStyle.setFont(font);

                    Cell cell = row.createCell(0);
                    cell.setCellValue(enterpriseCode);
                    // 设置样式
                    cell.setCellStyle(rowCellStyle);

                    Cell cell1 = row.createCell(1);
                    cell1.setCellValue(enterpriseName);
                    cell1.setCellStyle(rowCellStyle);

                    Cell cell2 = row.createCell(2);
                    if (organizationList.get(i-2).getLevel() == 1){
                        cell2.setCellValue(enterpriseCode);
                    }else {
                        cell2.setCellValue(organizationList.get(i-2).getCode());
                    }

                    cell2.setCellStyle(rowCellStyle);

                    Cell cell3 = row.createCell(3);
                    cell3.setCellValue(organizationList.get(i-2).getName());
                    cell3.setCellStyle(rowCellStyle);


                    for (int j = 4; j < 7; j++) { // 还3列需要填充
                        Cell cells = row.createCell(j);
                        cells.setCellStyle(rowCellStyle);
                    }
                }
                //组织类型下拉框
                CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 6500, 6, 6);
                DataValidationHelper helper = sheet.getDataValidationHelper();
                String[] strings = typeNames.toArray(new String[typeNames.size()]);
                DataValidationConstraint constraint = helper.createExplicitListConstraint(strings);
                DataValidation dataValidation = helper.createValidation(constraint, cellRangeAddressList);
                //处理Excel兼容性问题
                if (dataValidation instanceof XSSFDataValidation) {
                    dataValidation.setSuppressDropDownArrow(true);
                    dataValidation.setShowErrorBox(true);
                } else {
                    dataValidation.setSuppressDropDownArrow(false);
                }
                dataValidation.setEmptyCellAllowed(true);
                dataValidation.setShowPromptBox(true);
//                dataValidation.createPromptBox("提示", "只能选择下拉框里面的数据");
                sheet.addValidationData(dataValidation);

                workbook.write(response.getOutputStream());
            } catch (Exception e) {
                log.error(e.getMessage());
            } finally {
                if (bis != null) {
                    try {
                        bis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    //写入数据
    private void writeToExcel(List<OrganizationExcelDTO> dataList, String fileName,HttpServletResponse response,String[] headers,String exportName) throws Exception {
        try (Workbook workbook = new HSSFWorkbook()) {
            Sheet sheet = workbook.createSheet("组织数据");

            // 为标题行创建字体
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerFont.setFontName("宋体");

            // 使用字体创建单元格样式
            CellStyle headerCellStyle = workbook.createCellStyle();
            headerCellStyle.setFont(headerFont);
            headerCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 写入标题行
            Row headerRow = sheet.createRow(0);

            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerCellStyle);
            }


            int rowIndex = 1;
            for (OrganizationExcelDTO data : dataList) {
                Row row = sheet.createRow(rowIndex);

                // 基于OrganizationExcelDTO属性设置每个单元格的数据
                Cell cell1 = row.createCell(0);
                cell1.setCellValue(data.getEnterpriseCode());
                Cell cell2 = row.createCell(1);
                cell2.setCellValue(data.getEnterpriseName());
                Cell cell3 = row.createCell(2);
                cell3.setCellValue(data.getParentOrgCode());
                Cell cell4 = row.createCell(3);
                cell4.setCellValue(data.getParentOrgName());
                Cell cell5 = row.createCell(4);
                cell5.setCellValue(data.getOrgCode());
                Cell cell6 = row.createCell(5);
                cell6.setCellValue(data.getOrgName());
                Cell cell7 = row.createCell(6);
                cell7.setCellValue(data.getOrgTypeName());
                if ("batch-export".equals(exportName)){
                    Cell cell8 = row.createCell(7);
                    cell8.setCellValue(data.getManagerPhone());
                }
                if ("batch-error".equals(exportName)){
                    Cell cell8 = row.createCell(7);
                    cell8.setCellValue(data.getReason());
                }

                rowIndex++;
            }

            // 手动设置列宽
            sheet.setColumnWidth(0, 12 * 256); // 设置第一列的宽度为12个字符宽度
            sheet.setColumnWidth(1, 21 * 256); // 设置第二列的宽度为21个字符宽度
            sheet.setColumnWidth(2, 14 * 256);
            sheet.setColumnWidth(3, 21 * 256);
            sheet.setColumnWidth(4, 12 * 256);
            sheet.setColumnWidth(5, 21 * 256);
            sheet.setColumnWidth(6, 21 * 256);
            if ("batch-export".equals(exportName)){
                sheet.setColumnWidth(7, 20 * 256);
            }
            if ("batch-error".equals(exportName)){
                sheet.setColumnWidth(7, 40 * 256);
            }
            try {
                response.setContentType("application/octet-stream;charset=utf-8");
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName+".xls", "utf-8"));
                response.flushBuffer();
                workbook.write(response.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    //根据层级来封装组织数据
    private List<Organization> getOrganizationByLevel(int id,int level,List<Organization> organizationList){
        if (level >= 2){
            Organization organization = this.getById(id);
            organizationList.add(organization);
            getOrganizationByLevel(organization.getParentId(),organization.getLevel() - 1,organizationList);
        }else {
            return organizationList;
        }
        return organizationList;
    }

    //封装导出的组织数据
    private OrganizationExcelDTO getOrganizationExcel(Organization organizationExcel){
        OrganizationExcelDTO organizationExcelDTO = new OrganizationExcelDTO();
        Enterprise enterprise = enterpriseService.getById(organizationExcel.getEnterpriseId());
        organizationExcelDTO.setEnterpriseCode(enterprise.getCode());
        organizationExcelDTO.setEnterpriseName(enterprise.getName());

        QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
        organizationManagerQueryWrapper.eq("org_id",organizationExcel.getId());
        List<OrganizationManager> organizationManagers = organizationManagerService.list(organizationManagerQueryWrapper);
        if (organizationManagers.isEmpty()){
            log.info("该组织缺少组织负责人：{}",organizationExcel);
        }else {
            OrganizationManager manager = organizationManagers.get(0);
            Integer accountId = manager.getAccountId();
            Account account = accountService.getById(accountId);
            organizationExcelDTO.setManagerPhone(account.getName() + "/" + account.getPhone());
        }
        //上级组织名称和编码
        if (organizationExcel.getParentId() != 0){
            Organization orgParent = this.getById(organizationExcel.getParentId());
            if ( null !=orgParent){
                if (orgParent.getLevel() == 1){
                    Integer enterpriseId = orgParent.getEnterpriseId();
                    Enterprise enterpriseServiceById = enterpriseService.getById(enterpriseId);
                    organizationExcelDTO.setParentOrgCode(enterpriseServiceById.getCode());
                }else {
                    organizationExcelDTO.setParentOrgCode(orgParent.getCode());
                }
            }
            if (null !=orgParent && null != orgParent.getName()){
                organizationExcelDTO.setParentOrgName(orgParent.getName());
            }
        }
        //组织名称与编码
        if (null != organizationExcel.getCode() &&
                organizationExcel.getCode().trim().length() >= 6 &&
                organizationExcel.getCode().trim().length() <= 10){
            organizationExcelDTO.setOrgCode(organizationExcel.getCode());
        }
        organizationExcelDTO.setOrgName(organizationExcel.getName());

        //第三方组织信息
        if (null != organizationExcel.getThirdPartyId()){
            organizationExcelDTO.setThirdOrgId(organizationExcel.getThirdPartyId());
        }
        if (null != organizationExcel.getThirdPartyName()){
            organizationExcelDTO.setThirdOrgName(organizationExcel.getThirdPartyName());
        }
        //组织类型
        CustomOrganizationType customOrganizationType = customOrganizationTypeService.getById(organizationExcel.getCustomOrgType());
        if (null != customOrganizationType){
            organizationExcelDTO.setOrgTypeName(customOrganizationType.getName());
            organizationExcelDTO.setOrgTypeCode(customOrganizationType.getCode());
        }

        return organizationExcelDTO;
    }


    private boolean nameCheck(List<Organization> organizationList) {
        // 暂时不校验不同父级id下的名称重复 传到这里组织集合视为统一层级的下级
        List<String> names = new ArrayList<>(organizationList.size());
        for (Organization organization : organizationList) {
            if (names.contains(organization.getName())) {
                return false;
            }
            names.add(organization.getName());
        }
        return true;
    }

    private ResultJson batchFilter(Organization organization, Organization organization1) {
        if (20 < organization.getLevel()) {
            log.warn("创建的层级超过限制 20");
            throw new DataException("数据错误");
        }
        if (null == organization1) {
            return ResultJson.fail("创建组织失败，上级不存在");
        }
        if (null == organization) {
            log.warn("创建组织失败，组织为 null");
            return ResultJson.fail("参数错误");
        }
        if (StringUtils.isEmpty(organization.getName())) {
            log.warn("创建组织失败，缺少名称");
            return ResultJson.fail("缺少名称");
        }
        if (null == organization.getType()) {
            log.warn("创建组织失败，缺少类型");
            return ResultJson.fail("缺少类型");
        }
        // 一级组织设置0
        if (null == organization.getParentId()) {
            log.warn("创建组织失败，缺少上级组织信息");
            return ResultJson.fail("缺少上级组织信息");
        }
        //如果未写组织编码，则自动生成
        if (null == organization.getCode()){
            //新增组织编码保证企业下唯一
            Organization byId = this.getById(organization.getParentId());
            CodeGenerator codeGenerator = new CodeGenerator();
            String code = codeGenerator.generateUniqueCode(byId.getEnterpriseId(),this);
            organization.setCode(code);
        }

        if (null != organization.getCustomOrgType()){
            CustomOrganizationType customOrganizationType = customOrganizationTypeService.getById(organization.getCustomOrgType());
            if (null == customOrganizationType){
                return ResultJson.fail("自定义组织类型不存在");
            }
        }

        organization.setLevel(organization1.getLevel() + 1);
        organization.setIndustryId(organization1.getIndustryId());
        organization.setEnterpriseId(organization1.getEnterpriseId());
        if (null != organization1.getProjectId()) {
            organization.setProjectId(organization1.getProjectId());
        }

        //名称重复判断
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("parent_id", organization.getParentId());
        organizationQueryWrapper.eq("name", organization.getName());
        organizationQueryWrapper.eq("type", organization.getType());
        if (organization.getId() != null) {
            organizationQueryWrapper.ne("id", organization.getId());
        }
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (!organizations.isEmpty()) {
            log.error("创建组织失败，名称 {} 重复", organization.getName());
            return ResultJson.fail("名称重复");
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson deleteFollow(Integer id) {

        Organization organization = organizationDao.selectById(id);
        if (null == organization) {
            return ResultJson.fail("数据错误");
        }
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("enterprise_id", organization.getEnterpriseId());
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);

        List<Integer> deleteList = new ArrayList<>();
        deleteList.add(id);

        List<Organization> child = new ArrayList<>();
        child.add(organization);
        while (!child.isEmpty()) {
            List<Organization> current = null;
            current = organizations.stream().filter(o -> child.stream().map(c -> c.getId()).collect(Collectors.toList()).contains(o.getParentId())).collect(Collectors.toList());
            if (!current.isEmpty()) {
                deleteList.addAll(current.stream().map(c -> c.getId()).collect(Collectors.toList()));
            } else {
                child.clear();
            }
        }
        organizationDao.deleteBatchIds(deleteList);
        //记录日志
        organizationLogRecord(null, LogOperationTypeEnum.DELETE, "删除组织" + "【" + organization.getName() + "】", organization);

        organizationProducer.deletePush(JSON.toJSONString(Collections.singleton(organization)));
        return ResultJson.success("删除成功", deleteList);
    }

    @Override
    public ResultJson delete(Integer id, Account account) {
        Organization organization = organizationDao.selectById(id);
        if (null == organization) {
            return ResultJson.fail("组织不存在");
        }
        // 组织关联下级（组织或项目），区分返回不同message
        ResultJson resultJson = hasOrgOrProj(id);
        if (!resultJson.getState()) {
            return resultJson;
        }
        // 组织关联用户，禁止删除
        if (hasStaff(id)) {
            return ResultJson.fail("该组织下有用户，无法删除");
        }
        // 只能删除没有关联实例的类型，关联实例的类型要从具体的实例处删除
        if (OrganizationTypeEnum.ORG.id.intValue() == organization.getType()) {
            organizationDao.deleteById(id);
            //删除关联空间关系
            QueryWrapper<OrganizationSpace> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("organization_id",id);
            organizationSpaceService.remove(queryWrapper);
        } else if (OrganizationTypeEnum.AREA.id.intValue() == organization.getType()) {
            AreaQuery areaQuery = new AreaQuery();
            areaQuery.withOrgId(id);
            Area one = areaService.one(areaQuery, null);
            if (null == one) {
                return ResultJson.fail("区域不存在");
            }
            return areaService.delete(one.getId(), null);
        } else if (OrganizationTypeEnum.BUILDING.id.intValue() == organization.getType()) {
            QueryWrapper<Building> buildingQueryWrapper = new QueryWrapper<>();
            buildingQueryWrapper.eq("organization_id", id);
            Building one = buildingService.getOne(buildingQueryWrapper);
            if (null == one) {
                return ResultJson.fail("楼栋不存在");
            }
        } else if (OrganizationTypeEnum.FLOOR.id.intValue() == organization.getType()) {
            FloorQuery floorQuery = new FloorQuery();
            floorQuery.setOrgId(id);
            Floor floor = floorService.find(floorQuery);
            if (null == floor) {
                return ResultJson.fail("楼层不存在");
            }
        } else if (OrganizationTypeEnum.PUBLIC_AREA.id.intValue() == organization.getType()) {
            QueryWrapper<PublicArea> publicAreaQueryWrapper = new QueryWrapper<>();
            publicAreaQueryWrapper.eq("organization_id", id);
            PublicArea one = publicAreaService.getOne(publicAreaQueryWrapper);
            if (null == one) {
                return ResultJson.fail("公区不存在");
            }
        } else if (OrganizationTypeEnum.ROOM.id.intValue() == organization.getType()) {
            RoomQuery roomQuery = new RoomQuery();
            roomQuery.withOrgId(id);
            Room one = roomService.one(roomQuery);
            if (null == one) {
                return ResultJson.fail("房间不存在");
            }
        } else if (OrganizationTypeEnum.UNIT.id.intValue() == organization.getType() || OrganizationTypeEnum.BALCONY.id.intValue() == organization.getType()) {
            organizationDao.deleteById(id);
        } else {
            return ResultJson.fail("暂不支持类型");
        }
        //记录日志
        organizationLogRecord(account, LogOperationTypeEnum.DELETE, "删除组织" + "【" + organization.getName() + "】", organization);

        organizationProducer.deletePush(JSON.toJSONString(Collections.singleton(organization)));
        return ResultJson.success();
    }

    @Override
    public boolean saveBatch(Collection<Organization> entityList) {
        Boolean result = super.saveBatch(entityList);
        if (result && ChkUtil.isNotNull(entityList)) {
            organizationProducer.createPush(JSON.toJSONString(entityList));
        }
        return result;
    }

    @Override
    public ResultJson batchDelete(List<Integer> ids) {
        if (ChkUtil.isNotNull(ids)) {
            List<Organization> organizations = list(Wrappers.<Organization>lambdaQuery().in(Organization::getId, ids));
            if (this.removeByIds(ids)) {
                organizationProducer.deletePush(JSON.toJSONString(organizations));
            }
        }
        return ResultJson.success();
    }

    @Override
    public ResultJson update(Organization organization) {
        Organization organization1 = organizationDao.selectById(organization.getParentId());
        if (null == organization1) {
            return ResultJson.fail("上级不存在");
        }
        organization.setLevel(organization1.getLevel() + 1);
        ResultJson filter = filter(organization);
        if (organization.getParentId().intValue() == organization.getId()) {
            return ResultJson.fail("参数错误");
        }
        if (!filter.getState()) {
            return filter;
        }
        organizationDao.updateById(organization);

        if (null != organization.getViewStatus() && organization.getViewStatus().intValue() != OrganizationViewStatusEnum.LIMITED_ACCESS.code.intValue()) {
            QueryWrapper<OrganizationVisibility> organizationVisibilityQueryWrapper = new QueryWrapper<>();
            organizationVisibilityQueryWrapper.eq("org_id", organization.getId());
            organizationVisibilityService.remove(organizationVisibilityQueryWrapper);
        }
        //记录日志
        organizationLogRecord(null, LogOperationTypeEnum.UPDATE, "编辑组织" + "【" + organization.getName() + "】", organization);

        organizationProducer.updatePush(JSON.toJSONString(Collections.singleton(organization)));
        return ResultJson.success();
    }

    @Override
    public ResultJson update2(OrganizationDTO organizationDTO) {
        Organization organization = organizationDao.selectById(organizationDTO.getId());
        if (null == organization) {
            return ResultJson.fail("组织不存在");
        }
        update(organizationDTO);
        // 保存组织负责人 先清空 后保存
        QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
        organizationManagerQueryWrapper.eq("org_id", organization.getId());
        organizationManagerService.remove(organizationManagerQueryWrapper);
        if (CollectionUtils.isNotEmpty(organizationDTO.getManagerIds())) {
            StaffQuery staffQuery = new StaffQuery();
            staffQuery.setAccountIds(organizationDTO.getManagerIds());
            staffQuery.setEnterpriseId(organization.getEnterpriseId());
            List<StaffDTO> list = staffService.list(staffQuery);
            if (CollectionUtils.isNotEmpty(list)) {
                List<OrganizationManager> list1 = new ArrayList<>(list.size());
                for (StaffDTO staffDTO : list) {
                    OrganizationManager organizationManager = new OrganizationManager();
                    organizationManager.setAccountId(staffDTO.getAccountId());
                    organizationManager.setOrgId(organization.getId());
                    organizationManager.setAccountName(staffDTO.getName());
                    list1.add(organizationManager);
                }
                organizationManagerService.saveBatch(list1);
            }
        }
        //保存关联组织
        QueryWrapper<OrganizationSpace> organizationSpaceQueryWrapper = new QueryWrapper<>();
        organizationSpaceQueryWrapper.eq("organization_id", organizationDTO.getId());
        //先删后增
        organizationSpaceService.remove(organizationSpaceQueryWrapper);
        if (!CollectionUtils.isEmpty(organizationDTO.getSpaceIds())) {
            List<Integer> space = organizationDTO.getSpaceIds();

            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.in("id", space);
            organizationQueryWrapper.in("type", organizationTypeService.spaceIds());
            List<Organization> list = this.list(organizationQueryWrapper);
            if (!list.isEmpty()) {
                List<Integer> collect = list.stream().map(i -> i.getId()).collect(Collectors.toList());
//                List<Integer> collect1 = space.stream().filter(i -> collect.contains(i)).collect(Collectors.toList());
                if (!collect.isEmpty()) {
                    List<OrganizationSpace> organizationSpaces = new ArrayList<>(collect.size());
                    for (Integer integer : collect) {
                        OrganizationSpace organizationSpace = new OrganizationSpace();
                        organizationSpace.setOrganizationId(organization.getId());
                        organizationSpace.setSpaceId(integer);
                        organizationSpaces.add(organizationSpace);
                    }
                    // 保存关联空间
                    organizationSpaceService.saveBatch(organizationSpaces);
                }
            }
        }

        //更新组织表消息
        Organization organizationUpdate = new Organization();
        BeanUtils.copyProperties(organizationDTO,organizationUpdate);
        baseMapper.updateById(organizationUpdate);
        return ResultJson.success();
    }

    @Override
    public List<OrganizationDTO> tree(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        //设置房间功能类型
        setRoomFun(list);
        // 结果要形成树必须包含当前结果的所有父级结点
        if (null != organizationQuery.getEnterpriseId()) {
            list = parent(list, organizationQuery);
        }
        if (null != organizationQuery.getRoundLevel()) {
            return treeMaker(list);
        } else {
            // 过滤掉不属于查询条件中的内容
            if (organizationQuery != null) {
                if (null != organizationQuery.getTypes() && !organizationQuery.getTypes().isEmpty()) {
                    list = list.stream().filter(o -> organizationQuery.getTypes().contains(o.getType())).collect(Collectors.toList());
                }
            }
            return treeMaker(list);
        }
    }

    @Override
    public Page<Organization> orgPage(List<Integer> projectIds, Page page,List<Integer> types) {
        Page<Organization> result = organizationDao.orgPage(page,projectIds,types);
        return result;
    }

    /**
     * 设置房间的功能类型
     * @param list
     */
    private void setRoomFun(List<Organization> list){
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        //获得类型
        QueryWrapper<OrganizationType> queryWrapper = new QueryWrapper();
        queryWrapper.eq("code","room");
        OrganizationType organizationType = organizationTypeDao.selectOne(queryWrapper);
        if(organizationType == null){
            return;
        }
        for(Organization vo :list){
            if(organizationType.getId().toString().equals(vo.getType().toString())){
                //获得房间
                RoomQuery roomQuery = new RoomQuery();
                roomQuery.withOrgId(vo.getId());
                Room one = roomService.one(roomQuery);
                if(one != null && one.getFunctionType() != null) {
                    //获得房间的类型
                    SpaceFunctionType type = spaceFunctionTypeService.getById(one.getFunctionType());
                    if(type != null) {
                        vo.setFunctionName(type.getName());
                        vo.setFunctionType(type.getId());
                    }
                }
            }
        }
    }

    @Override
    public List<OrganizationDTO> treeWithManager(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        if(list.size() > 10000){
            throw new DataException("数据过多无法展示");
        }
        // 结果要形成树必须包含当前结果的所有父级结点
        if (null != organizationQuery.getEnterpriseId() && !organizationQuery.getIsRentSpace()) {
            list = parent(list, organizationQuery);
        }
        List<OrganizationDTO> organizationDTOS = new ArrayList<>(list.size());
        if (CollectionUtils.isNotEmpty(list)) {
            organizationDTOS = getOrganizationManager(list);
        }
        if (null != organizationQuery.getRoundLevel()) {
            return treeMakerDTO(organizationDTOS);
        } else {
            // 过滤掉不属于查询条件中的内容
            if (organizationQuery != null) {
                if (null != organizationQuery.getTypes() && !organizationQuery.getTypes().isEmpty()) {
                    organizationDTOS = organizationDTOS.stream().filter(o -> organizationQuery.getTypes().contains(o.getType())).collect(Collectors.toList());
                }
            }
            return treeMakerDTO(organizationDTOS);
        }
    }

    @Override
    public List<OrganizationDTO> treeCp(OrganizationQuery organizationQuery) {
        List<OrganizationDTO> result = null;
        List<Organization> list = list(organizationQuery);
        if(list.size() > 10000){
            throw new DataException("数据过多无法展示");
        }
        // 结果要形成树必须包含当前结果的所有父级结点
        if (null != organizationQuery.getEnterpriseId()) {
            list = parent(list, organizationQuery);
        }
        List<OrganizationDTO> organizationDTOS = new ArrayList<>(list.size());
        if (CollectionUtils.isNotEmpty(list)) {
            organizationDTOS = getOrganizationManager(list);
        }
        if (null != organizationQuery.getRoundLevel()) {
            result = treeMakerDTO(organizationDTOS);
        } else {
            // 过滤掉不属于查询条件中的内容
            if (organizationQuery != null) {
                if (null != organizationQuery.getTypes() && !organizationQuery.getTypes().isEmpty()) {
                    organizationDTOS = organizationDTOS.stream().filter(o -> organizationQuery.getTypes().contains(o.getType())).collect(Collectors.toList());
                }
            }
            result = treeMakerDTO(organizationDTOS);
        }
        //获得类型
        QueryWrapper<OrganizationType> queryWrapper = new QueryWrapper();
        queryWrapper.eq("code",organizationQuery.getCode());
        OrganizationType organizationType = organizationTypeDao.selectOne(queryWrapper);
        //处理不要节点,固定10次
        for (int i = 0; i < 10; i++) {
            dealTree(result,organizationType.getId(),organizationQuery.getStatus());
        }
        return result;
    }

    /**
     * 没有指定的子节点就去掉上级节点
     * @param list
     * @param type 判断层级
     * @param status 判断依据
     */
    private void dealTree(List<OrganizationDTO> list,Integer type,Integer status){
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        Iterator<OrganizationDTO> iterator = list.iterator();
        while (iterator .hasNext()) {
            OrganizationDTO vo = iterator.next();
            if(!type.toString().equals(vo.getType().toString())){
                //不是判断层级，并且没有子节点
                if(CollectionUtils.isEmpty(vo.getChildren())){
                    iterator.remove();
                }
            }else{
                //是判断层级，并且判断依据不满足
                if(status != null){
                    RoomQuery roomQuery = new RoomQuery();
                    roomQuery.withOrgId(vo.getId());
                    Room one = roomService.one(roomQuery);
                    if(one.getStatus() == null){
                        iterator.remove();
                    }else {
                        if (!status.toString().equals(one.getStatus().id.toString())) {
                            iterator.remove();
                        }
                    }
                }
            }
            dealTree(vo.getChildren(),type,status);
        }
    }

    /**
     * 获取所有父级
     *
     * @param list
     * @param organizationQuery
     * @return
     */
    private List<Organization> parent(List<Organization> list, OrganizationQuery organizationQuery) {
        if (list.isEmpty()) {
            return Collections.EMPTY_LIST;
        }
        List<Integer> levels = list.stream().map(i -> i.getLevel()).distinct().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        Integer maxLevel = levels.get(0);
        // 查询可能是父类的组织全集
        List<Organization> allCollection = new ArrayList<>();
        if(1 == list.size()){
            getParentSingle(allCollection, list.get(0));
        }else{
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
            organizationQueryWrapper.lt("level", maxLevel);
            allCollection = list(organizationQueryWrapper);
        }

        return listParentsByOrganization(list, allCollection, list);
    }

    /**
     * 避免查询过多的数据返回 总共最多10级
     * @param allCollection
     * @param organization
     */
    private void getParentSingle(List<Organization> allCollection, Organization organization) {

        if(1 == organization.getLevel()){
            return;
        }
        Organization p = this.getById(organization.getParentId());
        allCollection.add(p);
        getParentSingle(allCollection, p);
    }


    /**
     * 判断帐号所能查看的权限
     *
     * @param organizationQueryWrapper
     * @param accountId                （必填）
     */
    private void accountFilter(QueryWrapper<Organization> organizationQueryWrapper, Integer accountId,boolean flag) {
        if (null != accountId) {
            if (roleService.isSuperManager(accountId)) {
//                Account account = accountService.findById(accountId);
//                organizationQueryWrapper.eq("industry_id", account.getIndustryId());
            } else if (roleService.isEntManager(accountId)) {
                QueryWrapper<AccountOrganization> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("account_id", accountId);
                List<AccountOrganization> accountOrganizations = accountOrganizationDao.selectList(queryWrapper);
                if (accountOrganizations.isEmpty()) {
                    organizationQueryWrapper.eq("id", -1);
                    return;
                }
                Set<Integer> collect = accountOrganizations.stream().map(a -> a.getEnterpriseId()).collect(Collectors.toSet());
                if (collect.isEmpty()) {
                    log.warn("根据帐号查询组织结果为空");
                } else {
                    //获得运营商id
                    if (flag) {
                        Set<Integer> set = new HashSet<>();
                        for (Integer vi : collect) {
                            Integer entId = getEntId(vi);
                            set.add(entId);
                        }
                        organizationQueryWrapper.in("enterprise_id", set);
                    }else {
                        organizationQueryWrapper.in("enterprise_id", collect);
                    }
                }
            } else if (roleService.isOperationalManager(accountId)) {
                //todo 运维管理员暂未规划
            } else {
                // 普通帐号和项目管理员帐号的组织展示
                QueryWrapper<AccountProject> accountOrganizationQueryWrapper = new QueryWrapper<>();
                accountOrganizationQueryWrapper.eq("account_id", accountId);
                List<AccountProject> accountProjects = accountProjectDao.selectList(accountOrganizationQueryWrapper);
                if (accountProjects.isEmpty()) {
                    log.warn("普通帐号查询组织树，帐号未关联项目信息");
                    organizationQueryWrapper.eq("id", -1);
                    return;
                }
                List<Integer> prjectId = accountProjects.stream().map(ac -> ac.getProjectId()).collect(Collectors.toList());
                if (!prjectId.isEmpty()) {
                    organizationQueryWrapper.in("project_id", prjectId);
                } else {
                    log.warn("普通帐号根据帐号查询组织结果为空");
                    organizationQueryWrapper.eq("id", -1);
                }
            }
        }
    }

    private void handlerQueryParam(QueryWrapper<Organization> queryWrapper, OrganizationQuery organizationQuery) {
        if (null != organizationQuery) {
            if (null != organizationQuery.id) {
                queryWrapper.eq("id", organizationQuery.id);
            }
            if (null != organizationQuery.ids && !organizationQuery.ids.isEmpty()) {
                queryWrapper.in("id", organizationQuery.ids);
            }
            if (null != organizationQuery.parentId) {
                queryWrapper.eq("parent_id", organizationQuery.parentId);
            }
            // 企业没有平台概念故查询组织没有平台的条件了，因为企业改为后台创建获取到的平台是运管平台，而服务商则是在前台创建，
//            if (null != organizationQuery.industryId) {
//                queryWrapper.eq("industry_id", organizationQuery.industryId);
//            }
            if (null != organizationQuery.enterpriseId) {
                //queryWrapper.eq("enterprise_id", organizationQuery.enterpriseId);
                if(organizationQuery.flag){
                    Integer entId = getEntId(organizationQuery.enterpriseId);
                    queryWrapper.eq("enterprise_id", entId);
                }else{
                    queryWrapper.eq("enterprise_id", organizationQuery.enterpriseId);
                }
            }
            if (null != organizationQuery.level && !organizationQuery.level.isEmpty()) {
                queryWrapper.in("level", organizationQuery.level);
            }
            if (!StringUtils.isEmpty(organizationQuery.getKeywords())) {
                queryWrapper.like("name", organizationQuery.getKeywords());
            }
            if (!StringUtils.isEmpty(organizationQuery.getName())) {
                queryWrapper.like("name", organizationQuery.getName());
            }
            if (!StringUtils.isEmpty(organizationQuery.getName())) {
                queryWrapper.eq("name", organizationQuery.getName());
            }
            // 类型查询放在接口最后过滤，原因：不满足普通帐号根据项目id和roundLevel查询项目一下的组织信息，所以过滤类型放到接口最后处理
            if (CollectionUtils.isNotEmpty(organizationQuery.types)) {
                queryWrapper.in("type", organizationQuery.types);
            }
            if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
                queryWrapper.in("project_id", organizationQuery.projectIds);
            }
            if (null != organizationQuery.enterpriseIds && !organizationQuery.enterpriseIds.isEmpty()) {
                Set<Integer> collect = organizationQuery.enterpriseIds.stream().collect(Collectors.toSet());
                queryWrapper.in("enterprise_id", collect);
            }
            if (null != organizationQuery.excludeId) {
                queryWrapper.ne("id", organizationQuery.getExcludeId());
            }
            if (null != organizationQuery.organizationLogicQuery) {
                defLogicQuery(queryWrapper, organizationQuery.organizationLogicQuery);
            }
        }
    }

    /**
     * or 关系的条件处理
     *
     * @param queryWrapper
     * @param organizationLogicQuery
     */
    private void defLogicQuery(QueryWrapper<Organization> queryWrapper, OrganizationLogicQuery organizationLogicQuery) {
        if (null != organizationLogicQuery.getLogical() && LogicalEnum.OR == organizationLogicQuery.getLogical()) {
            if (StringUtils.isNotEmpty(organizationLogicQuery.getName())) {
                if (CollectionUtils.isEmpty(organizationLogicQuery.getIds())) {
                    queryWrapper.like("name", organizationLogicQuery.getName());
                } else {
                    queryWrapper.and(wrapper -> wrapper.like("name", organizationLogicQuery.getName()).or().in("id", organizationLogicQuery.getIds()));
                }
            }
        }
    }

    private void handlerQueryLevelParam(QueryWrapper<Organization> queryWrapper, OrganizationQuery organizationQuery) {
        if (null != organizationQuery) {
            if (null != organizationQuery.id) {
                queryWrapper.eq("id", organizationQuery.id);
            }
            if (null != organizationQuery.ids && !organizationQuery.ids.isEmpty()) {
                queryWrapper.in("id", organizationQuery.ids);
            }
            if (null != organizationQuery.parentId) {
                queryWrapper.eq("parent_id", organizationQuery.parentId);
            }
            // 企业没有平台概念故查询组织没有平台的条件了，因为企业改为后台创建获取到的平台是运管平台，而服务商则是在前台创建，
//            if (null != organizationQuery.industryId) {
//                queryWrapper.eq("industry_id", organizationQuery.industryId);
//            }
            if (null != organizationQuery.enterpriseId) {
                //queryWrapper.eq("enterprise_id", organizationQuery.enterpriseId);
                if(organizationQuery.flag){
                    Integer entId = getEntId(organizationQuery.enterpriseId);
                    queryWrapper.eq("enterprise_id", entId);
                }else{
                    queryWrapper.eq("enterprise_id", organizationQuery.enterpriseId);
                }
            }
            if (null != organizationQuery.level && !organizationQuery.level.isEmpty()) {
                queryWrapper.in("level", organizationQuery.level);
            }
            if (!StringUtils.isEmpty(organizationQuery.getKeywords())) {
                queryWrapper.like("name", organizationQuery.getKeywords());
            }
            if (!StringUtils.isEmpty(organizationQuery.getName())) {
                queryWrapper.like("name", organizationQuery.getName());
            }
            if (!StringUtils.isEmpty(organizationQuery.getName())) {
                queryWrapper.eq("name", organizationQuery.getName());
            }
            //类型查询放在接口最后过滤，原因：不满足普通帐号根据项目id和roundLevel查询项目一下的组织信息，所以过滤类型放到接口最后处理
//            if (null != organizationQuery.types && !organizationQuery.types.isEmpty()) {
//                queryWrapper.in("type", organizationQuery.types);
//            }
            if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
                queryWrapper.in("project_id", organizationQuery.projectIds);
            }
            if (null != organizationQuery.enterpriseIds && !organizationQuery.enterpriseIds.isEmpty()) {
                queryWrapper.in("enterprise_id", organizationQuery.enterpriseIds.stream().collect(Collectors.toSet()));
            }
            if (null != organizationQuery.excludeId) {
                queryWrapper.ne("id", organizationQuery.getExcludeId());
            }
            if (null != organizationQuery.organizationLogicQuery) {
                defLogicQuery(queryWrapper, organizationQuery.organizationLogicQuery);
            }
            //查询企业租赁空间
            if (organizationQuery.getIsRentSpace()){
                EnterpriseQuery enterpriseQuery = new EnterpriseQuery();
                enterpriseQuery.setIdList(Collections.singletonList(organizationQuery.getEnterpriseId()));
                List<EnterpriseSpace> enterpriseSpaces = enterpriseSpaceService.getEnterpriseSpace(enterpriseQuery).getResult();
                if (CollectionUtils.isNotEmpty(enterpriseSpaces)){
                    queryWrapper.in("id",enterpriseSpaces.stream().map(EnterpriseSpace::getOrganizationId).collect(Collectors.toList()));
                }else {
                    queryWrapper.eq("id",0);
                }
            }
        }
    }

    @Override
    public List<Organization> list(OrganizationQuery organizationQuery) {
        if (null == organizationQuery) {
            return Collections.emptyList();
        }
        // 处理请求参数
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        if (null == organizationQuery.roundLevel) {
            handlerQueryParam(organizationQueryWrapper, organizationQuery);
        } else {
            handlerQueryLevelParam(organizationQueryWrapper, organizationQuery);
        }
        if (!organizationQuery.getIsRentSpace()){
            accountFilter(organizationQueryWrapper, organizationQuery.accountId,organizationQuery.flag);
        }
        organizationQueryWrapper.last("limit 10000");
        organizationQueryWrapper.orderByAsc("if(sort_field is not null ,sort_field, 100000)","created_at");
        List<Organization> result = organizationDao.selectList(organizationQueryWrapper);
        List<Integer> resultIds = result.stream().map(Organization::getId).collect(Collectors.toList());
        if (null != organizationQuery.roundLevel && !result.isEmpty()) {
            List<Integer> enterpriseIds = result.stream().map(r -> r.getEnterpriseId()).distinct().collect(Collectors.toList());
            QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
            organizationQueryWrapper1.in("enterprise_id", enterpriseIds);
            List<Organization> aboutEnterprise = organizationDao.selectList(organizationQueryWrapper1);

            Map<Integer, Organization> idMap = aboutEnterprise.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
            if (0 < organizationQuery.roundLevel) {
                List<Organization> aboutOrganization = new ArrayList<>();
                for (Organization organization : result) {
                    Integer currentLv = organization.getLevel();
                    Organization currentOrg = organization;
                    while (currentLv > organization.getLevel() - organizationQuery.roundLevel) {
                        currentOrg = idMap.get(currentOrg.getParentId());
                        if (null == currentOrg) {
                            break;
                        }
                        aboutOrganization.add(currentOrg);
                        currentLv--;
                    }
                }
                result.addAll(aboutOrganization);
            } else {
                // 查询下级组织
                List<Organization> childs = getChilds(aboutEnterprise, result, Math.abs(organizationQuery.getRoundLevel()));
                result.addAll(childs);
            }
        }
        // reason l256
        if (organizationQuery != null) {
            if (null != organizationQuery.getTypes() && !organizationQuery.getTypes().isEmpty()) {
                result = result.stream().filter(o -> organizationQuery.getTypes().contains(o.getType())).collect(Collectors.toList());
            }
        }
        if (organizationQuery.getIsRentSpace()){
            //处理组织管理获取租赁空间数据
            List<Organization> needRemove = new ArrayList<>();
            for (Organization organization : result){
                List<Organization> child = child(new OrganizationQuery().withId(organization.getId()));
                List<Organization> isRentSpace = child.stream().filter(i -> resultIds.contains(i.getId())).collect(Collectors.toList());
                organization.setDisableCheckbox(!child.isEmpty() && (child.size() - isRentSpace.size()) > 0);
                log.info("子集为长度={}",child.size());
                log.info("在结果集中的子集长度={}" , isRentSpace.size());
                if (organization.getType().equals(Integer.valueOf(OrganizationTypeEnum.ENTERPRISE.getId()))){
                    needRemove.add(organization);
                }
            }
            result.removeAll(needRemove);
        }
        return result.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 获得运营商企业id
     * @return
     */
    private Integer getEntId(Integer enterpriseId){
        Integer entId = enterpriseId;
        //企业嵌套不超过5层
        for (int i = 0; i < 5; i++) {
            //判断当前id是不是运营商企业id
            QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
            entQueryWrapper.in("id", entId);
            List<Enterprise> entList = enterpriseDao.selectList(entQueryWrapper);
            if(CollectionUtil.isNotEmpty(entList)){
                Enterprise enterprise = entList.get(0);
                //获得运营商企业id
                if(enterprise.getType() != null && enterprise.getType().contains(EnterpriseTypeEnum.OPERATOR.id.toString())){
                    return enterprise.getId();
                }
                entId = enterprise.getParentId();
            }
        }
        return enterpriseId;
    }

    /**
     * 设置组织的管理员、关联空间、自定义组织类型
     *
     * @param organizations
     * @return
     */
    private <T extends Organization> List<OrganizationDTO> getOrganizationManager(List<T> organizations) {

        List<Integer> orgIds = organizations.stream().filter(i -> OrganizationTypeEnum.ORG.id.intValue() == i.getType()).map(i -> i.getId()).collect(Collectors.toList());

        Map<Integer, List<OrganizationManager>> map = new HashMap<>();
        Map<Integer,List<Organization>> spaceMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(orgIds)) {
            QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
            organizationManagerQueryWrapper.in("org_id", orgIds);
            List<OrganizationManager> list = organizationManagerService.list(organizationManagerQueryWrapper);
            if (!list.isEmpty()) {
                for (Integer orgId : orgIds) {
                    List<OrganizationManager> collect = list.stream().filter(i -> i.getOrgId().equals(orgId)).collect(Collectors.toList());
                    if (CollectionUtils.isNotEmpty(collect)) {
                        map.put(orgId, collect);
                    }
                }
            }
            QueryWrapper<OrganizationSpace> organizationSpaceQueryWrapper = new QueryWrapper<>();
            organizationManagerQueryWrapper.in("organization_id",orgIds);
            List<OrganizationSpace> organizationSpaces = organizationSpaceService.list(organizationSpaceQueryWrapper);
            if (!organizationSpaces.isEmpty()){
                List<Integer> spaceIds = organizationSpaces.stream().distinct().map(OrganizationSpace::getSpaceId).collect(Collectors.toList());
                List<Organization> spaces = organizationDao.selectBatchIds(spaceIds);
                Map<Integer,List<Integer>> idsMap = organizationSpaces.stream().collect(Collectors.groupingBy(OrganizationSpace::getOrganizationId,Collectors.mapping(OrganizationSpace::getSpaceId,Collectors.toList())));
                for (Map.Entry<Integer, List<Integer>> map1 : idsMap.entrySet()){
                    List<Organization> organizationList = spaces.stream().filter(i->map1.getValue().contains(i.getId())).collect(Collectors.toList());
                    spaceMap.put(map1.getKey(),organizationList);
                }
            }
        }
        //填充自定义组织类型+关联空间
        List<Integer> customTypeIds = organizations.stream().map(Organization::getCustomOrgType).collect(Collectors.toList());
        Map<Integer,CustomOrganizationType> customOrganizationTypeMap = new HashMap<>();
        if (!customTypeIds.isEmpty()){
            customTypeIds = customTypeIds.stream().distinct().collect(Collectors.toList());
            List<CustomOrganizationType> customOrganizationTypes = customOrganizationTypeService.listByIds(customTypeIds);
            customOrganizationTypeMap = customOrganizationTypes.stream().collect(Collectors.toMap(CustomOrganizationType::getId,customOrganizationType -> customOrganizationType));
        }
        List<OrganizationDTO> result = new ArrayList<>(organizations.size());
        for (Organization organization : organizations) {

            OrganizationDTO organizationDTO = new OrganizationDTO();
            BeanUtils.copyProperties(organization, organizationDTO);
            List<OrganizationManager> organizationManagers = map.get(organization.getId());
            if (CollectionUtils.isNotEmpty(organizationManagers)) {
                organizationDTO.setManager(organizationManagers);
            }
            if (null != organization.getCustomOrgType()){
                CustomOrganizationType customOrganizationType = customOrganizationTypeMap.get(organization.getCustomOrgType());
                organizationDTO.setCustomOrgTypeName(customOrganizationType.getName());
            }
            List<Organization> organizationList = spaceMap.get(organization.getId());
            if (CollectionUtils.isNotEmpty(organizationList)){
                organizationDTO.setSpaceNames(organizationList.stream().map(Organization::getName).collect(Collectors.toList()));
                organizationDTO.setSpaceIds(organizationList.stream().map(Organization::getId).collect(Collectors.toList()));
            }
            result.add(organizationDTO);
        }
        return result;
    }

    @Override
    public Map<String, Organization> listByChainName(OrganizationQuery organizationQuery) {
        if (CollectionUtils.isEmpty(organizationQuery.getChainNames()) || null == organizationQuery.getEnterpriseId()) {
            log.warn("根据链式名称查询组织参数错误");
            return Collections.emptyMap();
        }

        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        if (CollectionUtils.isNotEmpty(organizationQuery.getTypes())) {
            organizationQueryWrapper.in("type", organizationQuery.getTypes());
        }
        organizationQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
        organizationQueryWrapper.eq("is_deleted", false);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (organizations.isEmpty()) {
            log.info("该企业没有任何组织信息 {}", organizationQuery);
            return Collections.emptyMap();
        }

        List<String> chainNames = organizationQuery.getChainNames();

        Map<String, Organization> result = new HashMap<>();
        for (String cname : chainNames) {
            List<String> strings = Arrays.asList(cname.split(organizationQuery.getSplitChar()));
            String s = strings.get(strings.size() - 1);
            List<Organization> collect = organizations.stream().filter(i -> i.getName().equals(s)).collect(Collectors.toList());
            if (collect.isEmpty()) {
                continue;
            } else if (1 == collect.size()) {
                result.put(cname, collect.get(0));
            } else {
                // 判断上级
                String parentName;
                try {
                    parentName = strings.get(strings.size() - 2);
                } catch (Exception e) {
                    log.warn("组织数据错误，{} 找不到上级", JSONObject.toJSONString(collect));
                    continue;
                }
                List<Organization> collect1 = organizations.stream().filter(i -> i.getName().equals(parentName)).collect(Collectors.toList());
                if (collect1.isEmpty()) {
                    log.warn("组织数据错误，{} 找不到上级", JSONObject.toJSONString(collect));
                    continue;
                }
                Map<Integer, Organization> parentMap = collect1.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
                List<Organization> finalOrg = collect.stream().filter(i -> parentMap.get(i.getParentId()) != null).collect(Collectors.toList());
                if (CollectionUtils.isEmpty(finalOrg)) {
                    log.warn("组织数据错误，{} 找不到上级", JSONObject.toJSONString(collect));
                } else {
                    result.put(cname, finalOrg.get(0));
                }
            }
        }
        return result;
    }

    public List<Organization> getChilds(List<Organization> base, List<Organization> target, int level) {
        List<Organization> result = new ArrayList<>();
        result.addAll(target);
        for (int i = level; i > 0; i--) {
            List<Organization> next = getNext(base, target);
            result.addAll(next);
            target = next;
        }
        return result;
    }

    public List<Organization> getNext(List<Organization> base, List<Organization> target) {
        if (base.isEmpty() || target.isEmpty()) {
            return Collections.emptyList();
        }
        List<Integer> collect = target.stream().map(t -> t.getId()).collect(Collectors.toList());
        return base.stream().filter(b -> collect.contains(b.getParentId())).collect(Collectors.toList());
    }


    @Override
    public Organization find(OrganizationQuery organizationQuery) {
        if (null == organizationQuery) {
            return null;
        }

        if (StringUtils.isNotEmpty(organizationQuery.chainCode)) {
            //organizationQuery.withId(getIdByChainCode(organizationQuery));
            Integer idByChainCode = getIdByChainCode(organizationQuery);
            if(idByChainCode == null){
                return  null;
            }
            organizationQuery.withId(idByChainCode);
        }

        List<Organization> list = organizationDao.list(organizationQuery);
        if (list.isEmpty()) {
            return null;
        }

        // 需要特别处理 传入企业组织类型查询企业信息并且该帐号只在account_organization关联了项目没有关联企业的情况
        if (CollectionUtils.isNotEmpty(organizationQuery.types)) {
            OrganizationQuery entQuery = new OrganizationQuery();
            entQuery.withEnterpriseId(list.get(0).getEnterpriseId());
            List<Organization> entOrg = list(entQuery);
            // 过滤出完整的组织列表
            Map<Integer, Organization> allMap = entOrg.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key1));
            Map<Integer, Organization> baseMap = list.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key1));
            List<Organization> complate = getParent(baseMap, allMap);
            list = complate.stream().filter(c -> {
                return organizationQuery.types.contains(c.getType());
            }).collect(Collectors.toList());
        }
        if (list.isEmpty()) {
            return null;
        }
        if (1 < list.size()) {
            log.warn("查询到的不止一个结果 {} ", list.size());
        }
        return list.isEmpty() ? null : list.get(0);
    }

    /**
     * 根据最后两级编码查询最下级的id
     * @param organizationQuery
     * @return
     */
    private Integer getIdByChainCode(OrganizationQuery organizationQuery){
        String[] codes = organizationQuery.chainCode.split("-");
        List<String> strings = Arrays.asList(codes);
        if (CollectionUtils.isEmpty(strings) || strings.size() < 2) {
            log.info("查询空间参数错误 chaincode {}", organizationQuery.chainCode);
            return null;
        }
        String end = strings.get(strings.size() - 1).trim();
        String parent = strings.get(strings.size() - 2).trim();
        log.info("获取到的编码 1 {}, 2 {} ", end, parent);
        if (StringUtils.isEmpty(end) || StringUtils.isEmpty(parent)) {
            log.warn("根据编码 {} 查询组织失败", organizationQuery.chainCode);
            return null;
        }
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id");
        organizationQueryWrapper.in("code", parent);
        if(null != organizationQuery.getProjectId()){
            organizationQueryWrapper.eq("project_id", organizationQuery.getProjectId());
        }
        List<Organization> parents = organizationDao.selectList(organizationQueryWrapper);
        if(CollectionUtils.isEmpty(parents)){
            log.warn("上级不存在 {}", JSONObject.toJSONString(organizationQuery));
            return null;
        }
        QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
        organizationQueryWrapper1.in("parent_id", parents.stream().map(i -> i.getId()).collect(Collectors.toList()));
        organizationQueryWrapper1.eq("code", end);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper1);
        if(CollectionUtils.isEmpty(organizations)){
            log.warn("{} 的下级 {} 不存在 ", parents.stream().map(i -> i.getId()).collect(Collectors.toList()), end);
            return null;
        }
        return organizations.get(0).getId();
    }

    @Override
    public String fullName(OrganizationQuery organizationQuery) {
        if (null == organizationQuery.id) {
            log.warn("参数错误");
            return null;
        }
        if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
            projectToEnterpriseId(organizationQuery);
        }
        Organization organization = organizationDao.selectById(organizationQuery.id);
        if (null == organization) {
            log.warn("组织 {} 不存在", organizationQuery.id);
            return null;
        }
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "name", "parent_id", "enterprise_id", "level", "type");
        queryWrapper.eq("is_deleted", false);
        queryWrapper.eq("enterprise_id", organization.getEnterpriseId());
        if (null != organizationQuery.types && !organizationQuery.types.isEmpty()) {
            queryWrapper.in("type", organizationQuery.types);
        }
        List<Organization> organizations = organizationDao.selectList(queryWrapper);

        return getOrganizationChainName(organization, organizations, organizationQuery);
    }

    @Override
    public String fullCode(OrganizationQuery organizationQuery) {
        if (null == organizationQuery.id) {
            log.warn("参数错误");
            return null;
        }
        if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
            projectToEnterpriseId(organizationQuery);
        }
        Organization organization = organizationDao.selectById(organizationQuery.id);
        if (null == organization) {
            log.warn("组织 {} 不存在", organizationQuery.id);
            return null;
        }
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "name", "parent_id", "enterprise_id", "level", "type", "code");
        queryWrapper.eq("is_deleted", false);
        queryWrapper.eq("enterprise_id", organization.getEnterpriseId());
        if (null != organizationQuery.types && !organizationQuery.types.isEmpty()) {
            queryWrapper.in("type", organizationQuery.types);
        }

        QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
        organizationTypeQueryWrapper.select("id");
        organizationTypeQueryWrapper.in("view_type", Arrays.asList(ViewType.SPACE_DEFINED, ViewType.SPACE));
        List<OrganizationType> list = organizationTypeService.list(organizationTypeQueryWrapper);
        queryWrapper.in("type", list.stream().map(i -> i.getId()).collect(Collectors.toList()));
        List<Organization> organizations = organizationDao.selectList(queryWrapper);

        return getOrganizationChainCode(organization, organizations, organizationQuery);
    }

    @Override
    public Map<Integer, String> batchFullCode(OrganizationQuery organizationQuery) {
        if (null == organizationQuery.ids || organizationQuery.ids.isEmpty()) {
            log.warn("组织查询参数错误");
            return null;
        }
        if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
            projectToEnterpriseId(organizationQuery);
        }


        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id", "name", "parent_id", "enterprise_id", "level", "type", "code");
        organizationQueryWrapper.in("id", organizationQuery.ids);
        //目标组织（根据这个结果查询到与这个结果相关的上级）
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (organizations.isEmpty()) {
            log.warn("组织 {} 不存在", JSONObject.toJSONString(organizationQuery.ids));
            return null;
        }
        // 根据组织id 查出企业id 缩小检索范围
        List<Integer> enterpriseId = organizations.stream().map(o -> o.getEnterpriseId()).distinct().collect(Collectors.toList());
        if (enterpriseId.isEmpty()) {
            log.error("组织查询数据错误");
            return null;
        }
        QueryWrapper<OrganizationType> organizationTypeQueryWrapper = new QueryWrapper<>();
        organizationTypeQueryWrapper.select("id");

        organizationTypeQueryWrapper.in("view_type", Arrays.asList(ViewType.SPACE_DEFINED, ViewType.SPACE));
        List<OrganizationType> list = organizationTypeService.list(organizationTypeQueryWrapper);
        organizationQuery.withEnterpriseIds(enterpriseId);
        if (CollectionUtils.isEmpty(organizationQuery.types)) {
            organizationQuery.withTypes(list.stream().map(i -> i.getId()).collect(Collectors.toList()));
        }
        return batchPaddingParentCode(organizations, organizationQueryhandler(organizationQuery), organizationQuery);
    }

    @Override
    public List<Organization> batchFullCodeV2(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        if (list.isEmpty()){
            return list;
        }
        organizationQuery.setIds(list.stream().map(Organization::getId).collect(Collectors.toList()));
        Map<Integer, String> map = batchFullCode(organizationQuery);
        for (Organization organization : list){
            organization.setAllCode(map.get(organization.getId()));
        }
        return list;
    }

    private Map<Integer, String> batchPaddingParentCode(List<Organization> organizations, List<Organization> all, OrganizationQuery organizationQuery) {
        Map<Integer, String> result = new HashMap<>();
        for (Organization o : organizations) {
            Organization current = o;
            result.put(o.getId(), getOrganizationChainCode(current, all, organizationQuery));
        }
        return result;
    }

    private String getOrganizationChainCode(Organization current, List<Organization> all, OrganizationQuery organizationQuery) {
        StringBuilder sbd = new StringBuilder();
        String resultStr = null;
        List<Organization> result = getOrganizationChain(current, all, organizationQuery);
        if (!result.isEmpty()) {
            result = result.stream().sorted(Comparator.comparing(Organization::getLevel)).collect(Collectors.toList());

            for (Organization organization : result) {
                sbd.append(organization.getCode()).append("-");
            }
            resultStr = sbd.substring(0, sbd.length() - 1);
        }
        return resultStr;
    }

    private Map<Integer, String> batchPaddingParent(List<Organization> organizations, List<Organization> all, OrganizationQuery organizationQuery) {
        Map<Integer, String> result = new HashMap<>();
        for (Organization o : organizations) {
            Organization current = o;
            result.put(o.getId(), getOrganizationChainName(current, all, organizationQuery));
        }
        return result;
    }

    public String getOrganizationChainName(Organization current, List<Organization> all, OrganizationQuery organizationQuery) {
        StringBuilder sbd = new StringBuilder();
        String resultStr = null;
        List<Organization> result = getOrganizationChain(current, all, organizationQuery);
        if (!result.isEmpty()) {
            result = result.stream().sorted(Comparator.comparing(Organization::getLevel)).collect(Collectors.toList());

            for (Organization organization : result) {
                sbd.append(organization.getName()).append(organizationQuery.getSplitChar());
            }
            resultStr = sbd.substring(0, sbd.length() - 1);
        }
        return resultStr;
    }


    /**
     * 获取跟当前组织 current有关的所有组织，并且根据查询条件levels和types过滤，返回过滤后的集合
     * 例如： 某企业->某组织->某项目->某区域—>某楼栋
     * 条件： 1、某项目的id 2、组织类型为企业（enterprise）、楼栋（building）（或者层级（levels））
     * 结果： 结果为 某企业、某楼栋组成的list（或者结果根据层级（levels）展示）
     *
     * @param current
     * @param all
     * @param organizationQuery
     * @return
     */
    public List<Organization> getOrganizationChain(Organization current, List<Organization> all, OrganizationQuery organizationQuery) {
        Map<Integer, Organization> orgMap = all.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
        List<Organization> result = new ArrayList<>();
        result.add(current);
        // 上级添加
        Organization curr = current;
        final int deep = 200;
        int i = 0;
        while (null != curr) {
            if(deep < i){
                log.warn("超过指定递归深度");
                break;
            }
            curr = orgMap.get(curr.getParentId());
            if (null != curr) {
                result.add(curr);
            }
            i ++;
        }
        if (null != organizationQuery) {
            if (null != organizationQuery.level && !organizationQuery.level.isEmpty()) {
                result = result.stream().filter(r -> organizationQuery.level.contains(r.getLevel().intValue())).collect(Collectors.toList());
            }
            if (null != organizationQuery.types && !organizationQuery.types.isEmpty()) {
                result = result.stream().filter(r -> organizationQuery.types.contains(r.getType())).collect(Collectors.toList());
            }
        }
        return result;
    }

    @Override
    public Map<Integer, String> batchFullName(OrganizationQuery organizationQuery) {
        if (null == organizationQuery.ids || organizationQuery.ids.isEmpty()) {
            log.warn("组织查询参数错误");
            return null;
        }
        if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
            projectToEnterpriseId(organizationQuery);
        }

        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id", "name", "parent_id", "enterprise_id", "level", "type");
        organizationQueryWrapper.in("id", organizationQuery.ids);
        //目标组织（根据这个结果查询到与这个结果相关的上级）
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (organizations.isEmpty()) {
            log.warn("组织 {} 不存在", JSONObject.toJSONString(organizationQuery.ids));
            return null;
        }
        // 根据组织id 查出企业id 缩小检索范围
        List<Integer> enterpriseId = organizations.stream().map(o -> o.getEnterpriseId()).distinct().collect(Collectors.toList());
        if (enterpriseId.isEmpty()) {
            log.error("组织查询数据错误");
            return null;
        }
        organizationQuery.withEnterpriseIds(enterpriseId);
        return batchPaddingParent(organizations, organizationQueryhandler(organizationQuery), organizationQuery);
    }

    private List<Organization> organizationQueryhandler(OrganizationQuery organizationQuery) {
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id", "name", "parent_id", "enterprise_id", "level", "type", "code");
        queryWrapper.eq("is_deleted", false);
        if (null != organizationQuery.enterpriseId) {
            queryWrapper.eq("enterprise_id", organizationQuery.enterpriseId);
        }
        if (null != organizationQuery.enterpriseIds && !organizationQuery.enterpriseIds.isEmpty()) {
            queryWrapper.in("enterprise_id", organizationQuery.enterpriseIds.stream().collect(Collectors.toSet()));
        }
        if (null != organizationQuery.types && !organizationQuery.types.isEmpty()) {
            queryWrapper.in("type", organizationQuery.types);
        }
        // 企业下所有的组织
        return organizationDao.selectList(queryWrapper);
    }

    @Override
    public List<OrganizationDTO> projectChose(OrganizationQuery query) {
        if (null == query || null == query.accountId) {
            log.error("查询项目选择器参数错误");
            return Collections.emptyList();
        }
        query.withTypes(Arrays.asList(OrganizationTypeEnum.ENTERPRISE.id.intValue(), OrganizationTypeEnum.PROJECT.id.intValue(), OrganizationTypeEnum.ORG.id.intValue()));
        List<Organization> list = organizationDao.list(query);
        if (list.isEmpty()) {
            log.info("该帐号未关联组织信息");
            return Collections.emptyList();
        }
        List<Integer> orgId = list.stream().map(o -> o.getId()).collect(Collectors.toList());
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.select("id", "organization_id");
        projectQueryWrapper.in("organization_id", orgId);
        projectQueryWrapper.eq("status", 1);
        List<Project> projects = projectDao.selectList(projectQueryWrapper);
        if (projects.isEmpty()) {
            log.info("根据组织查询项目失败");
            return Collections.emptyList();
        }
        Map<Integer, Organization> base = list.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select();
        organizationQueryWrapper.in("enterprise_id", list.stream().map(i -> i.getEnterpriseId()).distinct().collect(Collectors.toList()));
        List<Organization> entOrgs = organizationDao.selectList(organizationQueryWrapper);
        Map<Integer, Organization> entMap = entOrgs.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (map1, map2) -> map1));
        return treeMaker(getParent(base, entMap));
    }

    @Override
    public List<OrganizationDTO> adminProjectChose(OrganizationQuery query) {
        if (null == query || null == query.accountId) {
            log.info("查询项目选择器参数错误");
            return Collections.emptyList();
        }
        List<Organization> list = null;
        query.withTypes(Arrays.asList(OrganizationTypeEnum.PROJECT.id.intValue(), OrganizationTypeEnum.ENTERPRISE.id.intValue(), OrganizationTypeEnum.ORG.id.intValue()));
        if (roleService.isSuperManager(query.getAccountId())) {
            list = selectBySuperManager(query);
        } else if (roleService.isEntManager(query.getAccountId())) {
            list = selectByEnterpriseManeger(query);
        } else {
            log.warn("暂不支持超管和企管以外的管理员查询");
            return Collections.emptyList();
        }
        if (list.isEmpty()) {
            return Collections.emptyList();
        }

        // 过滤掉没有项目的组织
        List<Organization> projectOrganization = list.stream().filter(l -> l.getType() == OrganizationTypeEnum.PROJECT.id.intValue()).collect(Collectors.toList());
        if (projectOrganization.isEmpty()) {
            log.warn("没有查询到项目");
            return Collections.emptyList();
        }
        List<Organization> result = new ArrayList<>(list.size());
        Map<Integer, Organization> map = list.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key2));
        // 设置递归深度
        int deep = 200;
        for (Organization organization : projectOrganization) {
            Organization current = organization;
            result.add(current);
            int i = 0;
            while (null != current) {
                if(deep < i){
                    log.warn("超过指定递归深度");
                    break;
                }
                current = map.get(current.getParentId());
                if (null != current) {
                    result.add(current);
                }
                i ++;
            }
        }
        Map<Integer, Organization> base = result.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key2));
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.in("enterprise_id", result.stream().map(i -> i.getEnterpriseId()).distinct().collect(Collectors.toList()));
        List<Organization> entOrgs = organizationDao.selectList(organizationQueryWrapper);
        Map<Integer, Organization> entMap = entOrgs.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (map1, map2) -> map1));
        return treeMaker(getParent(base, entMap));
    }

    /**
     * 根据超级管理员查询对应的组织信息
     *
     * @param organizationQuery
     * @return
     */
    private List<Organization> selectBySuperManager(OrganizationQuery organizationQuery) {
        Account account = accountService.findById(organizationQuery.getAccountId());

        // 超级管理员不需要根据帐号查询，改为根据业态查询
        organizationQuery.withAccountId(null);
        organizationQuery.withIndustryId(account.getIndustryId());
        List<Organization> list = organizationDao.list(organizationQuery);
        if (list.isEmpty()) {
            log.info("该帐号未关联组织信息");
            return Collections.emptyList();
        }
        return list;
    }

    /**
     * 根据企业管理员查询组织
     *
     * @param organizationQuery
     * @return
     */
    private List<Organization> selectByEnterpriseManeger(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        if (list.isEmpty()) {
            log.warn("该企业管理员 {} 查询不到关联的企业信息", organizationQuery.getAccountId());
            return Collections.emptyList();
        }
        return list;
    }

    private void projectToEnterpriseId(OrganizationQuery organizationQuery) {
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.select("id", "enterprise_id");
        projectQueryWrapper.eq("is_deleted", false);
        projectQueryWrapper.in("id", organizationQuery.projectIds);
        projectQueryWrapper.eq("status", 1);
        List<Project> projects = projectDao.selectList(projectQueryWrapper);
        if (!projects.isEmpty()) {
            List<Integer> collect = projects.stream().map(p -> p.getEnterpriseId()).collect(Collectors.toList());
            List<Integer> enterpriseIds = organizationQuery.getEnterpriseIds();
            if (null != enterpriseIds && !enterpriseIds.isEmpty()) {
                enterpriseIds.addAll(collect);
            } else {
                organizationQuery.withEnterpriseIds(collect);
            }
        }
    }

    /**
     * 获取与 base 有关的所有父节点
     *
     * @param base
     * @param currentEntOrg 当前企业下的所有组织
     * @return
     */
    private List<Organization> getParent(Map<Integer, Organization> base, Map<Integer, Organization> currentEntOrg) {
        Map<Integer, Organization> parentLevel = new HashMap<>();
        for (Map.Entry<Integer, Organization> org : base.entrySet()) {
            if (1 == org.getValue().getLevel().intValue()) {
                continue;
            }
            Organization organization = currentEntOrg.get(org.getValue().getParentId());
            if (null == organization) {
                continue;
            }
            parentLevel.put(organization.getId(), organization);
        }
        if (parentLevel.isEmpty()) {
            return base.entrySet().stream().map(en -> en.getValue()).collect(Collectors.toList());
        }
        getParent(parentLevel, currentEntOrg);
        base.putAll(parentLevel);
        return base.entrySet().stream().map(en -> en.getValue()).collect(Collectors.toList());
    }

    @Override
    public ResultJson create(Organization organization) {

        ResultJson filter = filter(organization);
        if (!filter.getState()) {
            return filter;
        }
        organizationDao.insert(organization);
        //记录日志
        organizationLogRecord(null, LogOperationTypeEnum.CREATE, "新增组织" + "【" + organization.getName() + "】", organization);

        organizationProducer.createPush(JSON.toJSONString(Collections.singleton(organization)));
        return ResultJson.success("操作成功", organization.getId());
    }

    private ResultJson filter(Organization organization) {
        if (null == organization.getLevel() || 20 < organization.getLevel()) {
            log.warn("创建的层级超过限制 20");
            throw new DataException("数据错误");
        }
        if (null == organization) {
            log.warn("组织为 null");
            return ResultJson.fail("参数错误");
        }
        // 一级组织设置0
        if (null == organization.getParentId()) {
            log.warn("缺少上级组织信息");
            return ResultJson.fail("缺少上级组织信息");
        }
        if (null == organization.getLevel() || organization.getLevel() > 1) {
            Organization organization1 = organizationDao.selectById(organization.getParentId());
            if (null == organization1) {
                log.error("上级组织不存在");
                return ResultJson.fail("上级组织不存在");
            }
            organization.setLevel(organization1.getLevel() + 1);
            if (organization.getLevel() > 2 && null != organization1.getProjectId()) {
                organization.setProjectId(organization1.getProjectId());
            }
            organization.setIndustryId(organization1.getIndustryId());
            organization.setEnterpriseId(organization1.getEnterpriseId());
            if (null != organization1.getProjectId()) {
                organization.setProjectId(organization1.getProjectId());
            }
        }
        if (null == organization.getEnterpriseId()) {
            log.warn("缺少企业信息");
            return ResultJson.fail("缺少企业信息");
        }
        if (StringUtils.isEmpty(organization.getName())) {
            log.warn("缺少名称");
            return ResultJson.fail("缺少名称");
        }
        if (null == organization.getType()) {
            log.warn("缺少类型");
            return ResultJson.fail("缺少类型");
        }

        //名称重复判断
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("parent_id", organization.getParentId());
        organizationQueryWrapper.eq("name", organization.getName());
        organizationQueryWrapper.eq("type", organization.getType());
        if (null != organization.getIndustryId()) {
            organizationQueryWrapper.eq("industry_id", organization.getIndustryId());
        } else {
            log.warn("组织未包含业态信息 {}", organization.toString());
        }
        if (organization.getId() != null) {
            organizationQueryWrapper.ne("id", organization.getId());
        }
        if (organization.getType().equals(Integer.valueOf(OrganizationTypeEnum.ENTERPRISE.id))){
            organizationQueryWrapper.eq("enterprise_id",organization.getEnterpriseId());
        }
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (!organizations.isEmpty()) {
            log.error("创建组织失败，名称 {} 重复", organization.getName());
            return ResultJson.fail("名称重复");
        }

        // 编码判断重复
        if(StringUtils.isNotEmpty(organization.getCode())){
            Organization parent = null;
            if (null != organization.getParentId()){
                parent = organizationDao.selectById(organization.getParentId());
            }
            if(parent != null && null != parent.getProjectId()){
                QueryWrapper<Organization> organizationQueryWrapper1 = new QueryWrapper<>();
                organizationQueryWrapper1.eq("code", organization.getCode());
                organizationQueryWrapper1.eq("project_id", parent.getProjectId());
                if (organization.getId() != null) {
                    organizationQueryWrapper1.ne("id", organization.getId());
                }
                List<Organization> organizations1 = organizationDao.selectList(organizationQueryWrapper1);
                if(!organizations1.isEmpty()){
                    log.error("创建组织失败，编码 {} 重复", organization.getCode());
                    throw new DataException("编码重复");
                }
            }

        }
        return ResultJson.success();
    }

    @Override
    public Organization getById(Integer id) {
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id);
        queryWrapper.eq("is_deleted", false);
        return organizationDao.selectOne(queryWrapper);
    }

    @Override
    public List<Organization> nodeListByType(OrgNodeDTO orgNodeDTO) {
        if (StringUtils.isEmpty(orgNodeDTO.getCode())) {
            return Collections.emptyList();
        }
        // 根据code查询 type => id
        List<OrganizationType> orgType = organizationTypeService.list(new QueryWrapper<OrganizationType>().eq("code", orgNodeDTO.getCode()));
        if (null == orgType) return Collections.emptyList();
        QueryWrapper<Organization> query = new QueryWrapper<>();
        query.eq("type", orgType.get(0).getId());
        if (null != orgNodeDTO.getProjectId()) {
            query.eq("project_id", orgNodeDTO.getProjectId());
        }
        List<Organization> list = organizationDao.selectList(query);
        return list;
    }

    /**
     * 查询父节点
     *
     * @param result             返回的结果集
     * @param organizations      所有组织集合
     * @param organizationIdList 需要查找父级的组织id
     * @return
     */
    private List<Organization> listParents(List<Organization> result, List<Organization> organizations, List<Integer> organizationIdList) {
        List<Organization> organizationList = organizations.stream()
                .filter(organization -> organizationIdList.contains(organization.getId()))
                .collect(Collectors.toList());
        return listParentsByOrganization(result, organizations, organizationList);
    }

    /**
     * 查询父节点
     *
     * @param result           返回的结果集(不需要包含生成传入的集合可以设置为 new ArrayLsit<>())
     * @param organizations    所有组织集合
     * @param organizationList 需要查找父级的组织
     * @return
     */
    private List<Organization> listParentsByOrganization(List<Organization> result, List<Organization> organizations, List<Organization> organizationList) {
        List<Integer> parentIds = organizationList.stream().filter(o -> null != o.getParentId() && 0 != o.getParentId()).map(o -> o.getParentId()).collect(Collectors.toList());
        List<Integer> resultIds = result.stream().map(r -> r.getId()).collect(Collectors.toList());
        parentIds.removeAll(resultIds);
        if (CollectionUtils.isEmpty(parentIds)) {
            return result;
        }
        List<Organization> parentOrg = organizations.stream().filter(o -> parentIds.contains(o.getId())).collect(Collectors.toList());
        result.addAll(parentOrg);
        organizations.removeAll(parentOrg);
        return this.listParentsByOrganization(result, organizations, parentOrg);
    }

    /**
     * 查询父节点
     *
     * @param result           返回的结果集(不需要包含生成传入的集合可以设置为 new ArrayLsit<>())
     * @param organizations    所有组织集合
     * @param organizationList 需要查找父级的组织
     * @return
     */
    private List<Organization> getParents(List<Organization> result, List<Organization> organizations, List<Organization> organizationList) {
        List<Integer> parentIds = organizationList.stream().filter(o -> null != o.getParentId() && 0 != o.getParentId()).map(o -> o.getParentId()).collect(Collectors.toList());
        List<Integer> resultIds = result.stream().map(r -> r.getId()).collect(Collectors.toList());
        parentIds.removeAll(resultIds);
        if (CollectionUtils.isEmpty(parentIds)) {
            return result;
        }
        List<Organization> parentOrg = organizations.stream().filter(o -> parentIds.contains(o.getId())).collect(Collectors.toList());
        result.addAll(parentOrg);
        return this.getParents(result, organizations, parentOrg);
    }
    /**
     * 根据当前集合生成一个组织树
     *
     * @return
     */
    private List<OrganizationDTO> treeMaker(List<Organization> organizations) {
        if (organizations.isEmpty()) {
            return Collections.emptyList();
        }
        List<Organization> sort = organizations.stream().distinct().sorted(Comparator.comparing(Organization::getLevel)).collect(Collectors.toList());
        // get top element
        Organization organization = sort.get(0);
        List<Organization> tops = sort.stream().parallel().filter(s -> organization.getLevel() == s.getLevel()).collect(Collectors.toList());

        // 封装根节点数据
        List<OrganizationDTO> organizationDTOList = orgWrapper(tops);

        // 过滤掉根节点，剩余子节点
        List<Organization> nodes = organizations.stream().parallel()
                .filter(o -> !tops.stream().map(Organization::getId).collect(Collectors.toList()).contains(o.getId()))
                .collect(Collectors.toList());

        organizationDTOList.stream().forEach(organizationDTO -> organizationDTO.setChildren(this.listChildren(nodes, organizationDTO.getId())));

        return organizationDTOList;
    }

    /**
     * 根据当前集合生成一个组织树
     *
     * @return
     */
    private List<OrganizationDTO> treeMakerDTO(List<OrganizationDTO> organizations) {
        if (organizations.isEmpty()) {
            return Collections.emptyList();
        }
        List<OrganizationDTO> sort = organizations.stream().sorted(Comparator.comparing(OrganizationDTO::getLevel)).collect(Collectors.toList());
        // get top element
        Organization organization = sort.get(0);
        List<OrganizationDTO> tops = sort.stream().parallel().filter(s -> organization.getLevel() == s.getLevel()).collect(Collectors.toList());

        // 封装根节点数据
        List<OrganizationDTO> organizationDTOList = orgDTOWrapper(tops);

        // 过滤掉根节点，剩余子节点
        List<OrganizationDTO> nodes = organizations.stream().parallel()
                .filter(o -> !tops.stream().map(OrganizationDTO::getId).collect(Collectors.toList()).contains(o.getId()))
                .collect(Collectors.toList());

        organizationDTOList.stream().forEach(organizationDTO -> {
            List<OrganizationDTO> organizationDTOS = this.listDTOChildren(nodes, organizationDTO.getId());
            organizationDTO.setChildren(organizationDTOS);
            organizationDTO.setHasChild(!CollectionUtils.isEmpty(organizationDTOS));
            if(CollectionUtils.isNotEmpty(organizationDTOS)){
                List<OrganizationDTO> collect = organizationDTOS.stream().filter(i -> i.getType() == OrganizationTypeEnum.ORG.id.intValue()).collect(Collectors.toList());
                organizationDTO.setHasOrgChild(!CollectionUtils.isEmpty(collect));
            }
        });

        return organizationDTOList;
    }

    /**
     * Organization -> OrganizationDTO
     *
     * @param tops
     * @return
     */
    private List<OrganizationDTO> orgWrapper(List<Organization> tops) {
        // 封装根节点数据
        return tops.stream().map(o -> {
            OrganizationDTO organizationDTO = new OrganizationDTO();
            BeanUtils.copyProperties(o, organizationDTO);
            StringBuilder sbd = new StringBuilder();
            sbd.append(o.getId()).append("-").append(o.getName());
            organizationDTO.setKeywords(sbd.toString());
            organizationDTO.setUniqueKey((o.getProjectId() == null ? "#" : o.getProjectId()) + "-" + o.getId() + "-" + o.getName());
            return organizationDTO;
        }).collect(Collectors.toList());
    }

    /**
     * Organization -> OrganizationDTO
     *
     * @param tops
     * @return
     */
    private List<OrganizationDTO> orgDTOWrapper(List<OrganizationDTO> tops) {
        // 封装根节点数据
        return tops.stream().map(o -> {
            StringBuilder sbd = new StringBuilder();
            sbd.append(o.getId()).append("-").append(o.getName());
            o.setKeywords(sbd.toString());
            o.setUniqueKey((o.getProjectId() == null ? "#" : o.getProjectId()) + "-" + o.getId() + "-" + o.getName());
            return o;
        }).collect(Collectors.toList());
    }

    /**
     * 筛选子节点
     *
     * @param organizations 总集合
     * @param parentId
     * @return
     */
    private List<OrganizationDTO> listChildren(List<Organization> organizations, Integer parentId) {

        if (null == organizations || organizations.isEmpty()) {
            return Collections.emptyList();
        }
        // 过滤出子节点
        List<Organization> organizationList = organizations.stream().parallel()
                .filter(organization -> organization.getParentId().equals(parentId)).distinct()
                .collect(Collectors.toList());
        // 移除处理节点
        organizations.removeAll(organizationList);
        // 封装子节点
        return organizationList.stream().map(organization -> {
            OrganizationDTO organizationDTO = new OrganizationDTO();
            BeanUtils.copyProperties(organization, organizationDTO);
            StringBuilder sbd = new StringBuilder();
            sbd.append(organization.getId()).append("-").append(organization.getName());
            organizationDTO.setKeywords(sbd.toString());

            organizationDTO.setUniqueKey((organization.getProjectId() == null ? "#" : organization.getProjectId()) + "-" + organization.getId() + "-" + organization.getName());
            organizationDTO.setChildren(this.listChildren(organizations, organizationDTO.getId()));
            return organizationDTO;
        }).collect(Collectors.toList());
    }

    /**
     * 筛选子节点
     *
     * @param organizations 总集合
     * @param parentId
     * @return
     */
    private List<OrganizationDTO> listDTOChildren(List<OrganizationDTO> organizations, Integer parentId) {

        if (null == organizations || organizations.isEmpty()) {
            return Collections.emptyList();
        }
        // 过滤出子节点
        List<OrganizationDTO> organizationList = organizations.stream().parallel()
                .filter(organization -> organization.getParentId().equals(parentId))
                .collect(Collectors.toList());
        // 移除处理节点
        List<Integer> childId = organizationList.stream().map(i -> i.getId()).collect(Collectors.toList());
        List<OrganizationDTO> collect1 = organizations.stream().filter(i -> !childId.contains(i)).collect(Collectors.toList());
        // 封装子节点
        return organizationList.stream().map(organization -> {
            StringBuilder sbd = new StringBuilder();
            sbd.append(organization.getId()).append("-").append(organization.getName());
            organization.setKeywords(sbd.toString());
            organization.setUniqueKey((organization.getProjectId() == null ? "#" : organization.getProjectId()) + "-" + organization.getId() + "-" + organization.getName());
            List<OrganizationDTO> organizationDTOS = this.listDTOChildren(collect1, organization.getId());
            organization.setHasChild(!CollectionUtils.isEmpty(organizationDTOS));
            organization.setChildren(organizationDTOS);
            organization.setHasOrgChild(!CollectionUtils.isEmpty(organizationDTOS));
            return organization;
        }).collect(Collectors.toList());
    }


    @Override
    public Boolean hasChild(Integer id) {
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id");
        organizationQueryWrapper.eq("parent_id", id);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        return !organizations.isEmpty();
    }


    private ResultJson hasOrgOrProj(Integer id) {
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("is_deleted", 0)
                .eq("parent_id", id);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        for (Organization organization : organizations) {
            if (organization.getType() == OrganizationTypeEnum.ORG.id.intValue()) {
                return ResultJson.fail("该组织下有组织，无法删除");
            } else if (organization.getType() == OrganizationTypeEnum.PROJECT.id.intValue()) {
                return ResultJson.fail("该组织下有项目，无法删除");
            }
        }
        return ResultJson.success();
    }


    private Boolean hasStaff(Integer id) {
        QueryWrapper<StaffOrganization> staffOrgQueryWrapper = new QueryWrapper<>();
        staffOrgQueryWrapper.in("org_id", id);
        List<StaffOrganization> staffOrganizations = staffOrganizationDao.selectList(staffOrgQueryWrapper);
        return !staffOrganizations.isEmpty();
    }

    @Override
    public List<Organization> child(OrganizationQuery query) {
        if (null == query) {
            log.warn("空参返回");
            return Collections.emptyList();
        }
        if (null == query.id && CollectionUtils.isEmpty(query.ids)) {
            log.warn("查询参数错误");
            return Collections.emptyList();
        }
        List<Organization> result = new ArrayList<>();
        List<Organization> list = this.list(query);
        if (list.isEmpty()) {
            log.warn("组织不存在");
            return Collections.emptyList();
        }
        List<Organization> sort = list.stream().sorted(Comparator.comparing(Organization::getLevel)).collect(Collectors.toList());
        Organization organization = sort.get(0);
        result.addAll(sort);
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.eq("enterprise_id", organization.getEnterpriseId());
        organizationQueryWrapper.gt("level", organization.getLevel());
        List<Organization> base = organizationDao.selectList(organizationQueryWrapper);

        for (Organization organization1 : list) {
            List<Organization> organizations = this.listChild(base, organization1);
            result.addAll(organizations);
        }
        if (CollectionUtils.isNotEmpty(query.types)) {
            result = result.stream().filter(i -> query.types.contains(i.getType())).collect(Collectors.toList());
        }
        return result.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public Map<Integer, List<Organization>> findChildByProject(OrganizationQuery query) {
        if (null == query) {
            log.warn("空参返回");
            return null;
        }
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("project_id",query.projectIds);
        queryWrapper.eq("type",OrganizationTypeEnum.BUILDING.id);
        List<Organization> organizationList = list(queryWrapper);
        if (organizationList.isEmpty()){
            return null;
        }
//        Map<Integer,List<Organization>> groupByParentId = organizationList.stream().collect(Collectors.groupingBy(Organization :: getParentId));
        Map<Integer, List<Organization>> result = new HashMap<>();
//        int minLevel = Collections.min(query.level);
//        organizationList = organizationList.stream().filter(i -> i.getLevel().equals(minLevel)).collect(Collectors.toList());
//        for (Organization organization : organizationList){
//            if (!groupByParentId.containsKey(organization.getId())){
//                continue;
//            }
//            List<Organization> organizations = new ArrayList<>(groupByParentId.get(organization.getId()));
//            if (!query.getTypes().contains(organizations.get(0).getType())){
//                for (Organization organization1 : groupByParentId.get(organization.getId())){
//                    if (!groupByParentId.containsKey(organization1.getId())){
//                        continue;
//                    }
//                    organizations.addAll(groupByParentId.get(organization1.getId()));
//                }
//            }
//            result.put(organization.getId(),organizations.stream().filter(i -> query.getTypes().contains(i.getType())).collect(Collectors.toList()));
//        }
        Organization organization = organizationList.get(0);
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id","type","level","parent_id");
        organizationQueryWrapper.eq("enterprise_id", organization.getEnterpriseId());
        organizationQueryWrapper.gt("level", organization.getLevel());
        List<Organization> base = organizationDao.selectList(organizationQueryWrapper);
        for (Organization o : organizationList){
            List<Organization> child = this.listChild(base, o);
            if (null != query.getTypes() && !query.getTypes().isEmpty()){
                child = child.stream().filter(i -> query.getTypes().contains(i.getType())).collect(Collectors.toList());
            }
            result.put(o.getId(),child);
        }
        return result;
    }

    @Override
    public ResultJson refreshSort(OrganizationQuery organizationQuery) {
        List<Organization> organizationList = this.list(organizationQuery);
        if (null == organizationList || organizationList.isEmpty()){
            return ResultJson.success("刷新成功");
        }
        organizationList = organizationList.stream().distinct().collect(Collectors.toList());
//        Map<Integer,Organization> organizationMap = organizationList.stream().collect(Collectors.toMap(Organization::getId, Function.identity()));
//        List<List<Area>> parts = Lists.partition(areas, 500);
        for (int i = 0; i < organizationList.size(); i++) {
            organizationList.get(i).setSortField(i+1);
        }
        this.updateBatchById(organizationList);
        return ResultJson.success("刷新成功");
    }

    /**
     * 返回list结构
     *
     * @param base   集合里的level必须是大于parentId的level
     * @param parent
     * @return
     */
    private List<Organization> listChild(List<Organization> base, Organization parent) {
        List<Organization> result = new ArrayList<>();
        if (CollectionUtils.isEmpty(base)) {
            return Collections.emptyList();
        }

        List<Integer> levels = base.stream().map(i -> i.getLevel()).distinct().sorted().filter(i -> i.intValue() > parent.getLevel().intValue()).collect(Collectors.toList());

        List<Integer> parents = Arrays.asList(parent.getId());
        for (Integer level : levels) {
            List<Integer> parentsCopy = parents;
            List<Organization> collect = base.stream().filter(i -> i.getLevel() == level.intValue()).filter(j -> parentsCopy.contains(j.getParentId())).collect(Collectors.toList());
            if (collect.isEmpty()) {
                break;
            }
            result.addAll(collect);
            parents = collect.stream().map(i -> i.getId()).collect(Collectors.toList());
        }
        return result;
    }

    @Override
    public Map<Integer, List<Organization>> findDefault(OrganizationQuery organizationQuery) {
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();

        accountFilter(organizationQueryWrapper, organizationQuery.accountId,false);
        handlerQueryParam(organizationQueryWrapper, organizationQuery);
        List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
        if (organizations.isEmpty()) {
            return Collections.emptyMap();
        }
        if (null != organizationQuery.projectIds && !organizationQuery.projectIds.isEmpty()) {
            List<Organization> projects = organizations.stream().filter(o -> o.getType() == OrganizationTypeEnum.PROJECT.id.intValue()).collect(Collectors.toList());
            return getDefaultTypeOrganization(projects);
        }
        return null;
    }

    @Override
    public Page<Organization> page(OrganizationQuery organizationQuery, Page page) {
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        if (null != organizationQuery) {
            if (null != organizationQuery.parentId) {
                organizationQueryWrapper.eq("parent_id", organizationQuery.parentId);
            }
            if (null != organizationQuery.types) {
                organizationQueryWrapper.in("type", organizationQuery.types);
            }
            if (StringUtils.isNotEmpty(organizationQuery.getKeywords())) {
                organizationQueryWrapper.like("name", organizationQuery.getKeywords().trim());
            }
        } else {
            log.warn("组织查询了全部数据");
        }
        organizationQueryWrapper.orderByAsc("if(sort_field is not null ,sort_field, 100000)","created_at");
        return organizationDao.selectPage(page, organizationQueryWrapper);
    }

    @Override
    public List<OrganizationDTO> projectChoseV2(@NotNull OrganizationQuery query) {
        query.withTypes(Arrays.asList(OrganizationTypeEnum.PROJECT.id.intValue()));

        List<Organization> list = null;
        if (null != query.getAccountId() && roleService.isSuperManager(query.getAccountId())) {
            list = selectBySuperManager(query);
        } else if (null != query.getAccountId() && roleService.isEntManager(query.getAccountId())) {
            list = selectByEnterpriseManeger(query);
        } else {
            list = organizationDao.list(query);
        }
        if (list.isEmpty()) {
            log.info("查询到的项目结果为空");
            return Collections.emptyList();
        }
        log.info("当前查询出的项目为 {}", JSONObject.toJSONString(list.stream().map(l -> l.getName()).collect(Collectors.toList())));

        // 根据当前查询出的项目进行企业分组
        List<Integer> enterpriseIds = list.stream().map(l -> l.getEnterpriseId()).distinct().collect(Collectors.toList());
        QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
        enterpriseQueryWrapper.select("id", "name", "organization_id", "industry_id");
        enterpriseQueryWrapper.in("id", enterpriseIds);
        List<Enterprise> enterprises = enterpriseDao.selectList(enterpriseQueryWrapper);

        List<OrganizationDTO> result = new ArrayList<>(enterprises.size());

        for (Enterprise enterprise : enterprises) {
            OrganizationDTO organizationDTO = new OrganizationDTO();
            organizationDTO.setEnterpriseId(enterprise.getId());
            organizationDTO.setId(enterprise.getOrganizationId());
            organizationDTO.setName(enterprise.getName());
            organizationDTO.setIndustryId(enterprise.getIndustryId());
            organizationDTO.setType(OrganizationTypeEnum.ENTERPRISE.id.intValue());
            organizationDTO.setChildren(list.stream().filter(l -> l.getEnterpriseId() == enterprise.getId().intValue()).map(o -> {
                OrganizationDTO organizationDTO1 = new OrganizationDTO();
                BeanUtils.copyProperties(o, organizationDTO1);
                return organizationDTO1;
            }).collect(Collectors.toList()));
            result.add(organizationDTO);
        }
        return result;
    }

    @Override
    public List<Project> projectChoseV3(OrganizationQuery organizationQuery,Account account) {
        List<Role> roleListByAccountId = roleService.getRoleListByAccountId(organizationQuery.getAccountId());
        List<Integer> enterpriseIds = new ArrayList<>();
        for (Role role : roleListByAccountId) {
            if(role.getType() == RoleTypeEnum.MANAGER.code){
                enterpriseIds.add(role.getEnterpriseId());
            }
        }
        QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
        projectQueryWrapper.select("id", "name","code","organization_id", "enterprise_id","industry_id","picture_url","scene_id");
        Enterprise enterprise = null;
        if(null != organizationQuery.getEnterpriseId()){
            enterprise = enterpriseService.findById(organizationQuery.getEnterpriseId());
        }
        // 当前企业的企业管理员返回企业下的所有项目
        if (organizationQuery.getIsAccountAuth()){
            if(!enterpriseIds.isEmpty() && enterpriseIds.contains(organizationQuery.getEnterpriseId())){
                if(null != organizationQuery.getEnterpriseId()){
                    if(enterprise.getType().toString().contains(EnterpriseTypeEnum.OPERATOR.id.toString())){
                        if(enterpriseIds.contains(organizationQuery.getEnterpriseId())){
                            projectQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
                        }else{
                            log.warn("企业id {} 未授权, 帐号 {}", organizationQuery.getEnterpriseId(), organizationQuery.getAccountId());
                            return Collections.emptyList();
                        }
                    }else{
                        QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
                        enterpriseProjectQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
                        List<EnterpriseProject> list2 = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
                        if(list2.isEmpty()){
                            return Collections.emptyList();
                        }
                        projectQueryWrapper.in("id", list2.stream().map(i -> i.getProjectId()).collect(Collectors.toList()));
                    }
                }else{
                    QueryWrapper<Project> projectQueryWrapper1 = new QueryWrapper<>();
                    projectQueryWrapper1.select("id");
                    projectQueryWrapper1.in("enterprise_id", enterpriseIds);
                    projectQueryWrapper1.eq("is_deleted", false);
                    List<Project> list = projectService.list(projectQueryWrapper1);
                    List<Integer> projectIds = new ArrayList<>();
                    if(!list.isEmpty()){
                        projectIds.addAll(list.stream().map(i -> i.getId()).collect(Collectors.toList()));
                    }
                    // 如果是非运营商的补充授权项目
                    QueryWrapper<Enterprise> enterpriseQueryWrapper = new QueryWrapper<>();
                    enterpriseQueryWrapper.select("id", "type");
                    enterpriseQueryWrapper.in("id", enterpriseIds);
                    enterpriseQueryWrapper.eq("is_deleted", false);
                    List<Enterprise> list1 = enterpriseService.list(enterpriseQueryWrapper);
                    List<Integer> entIds = new ArrayList<>();
                    for (Enterprise enterprise1 : list1) {
                        if(!enterprise1.getType().equals(EnterpriseTypeEnum.OPERATOR.id.toString())){
                            entIds.add(enterprise1.getId());
                        }
                    }
                    if(!entIds.isEmpty()){
                        // 查询入驻企业的授权项目
                        QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
                        enterpriseProjectQueryWrapper.in("enterprise_id", entIds);
                        List<EnterpriseProject> list2 = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
                        if(!list2.isEmpty()){
                            projectIds.addAll(list2.stream().map(i -> i.getProjectId()).distinct().collect(Collectors.toList()));
                        }
                    }
                    projectQueryWrapper.in("id", projectIds);
                }
            }else {
                //QueryWrapper<AccountProject> accountProjectQueryWrapper = new QueryWrapper<>();
                //accountProjectQueryWrapper.eq("account_id", organizationQuery.getAccountId());
                //List<AccountProject> accountProjects = accountProjectService.list(accountProjectQueryWrapper);
                //if(accountProjects.isEmpty()){
                //    log.warn("帐号没有关联项目数据");
                //    return Collections.emptyList();
                //}
                //List<Integer> collect = accountProjects.stream().map(i -> i.getProjectId()).collect(Collectors.toList());
                //如果不是企业管理员，则需要通过权限组获取账号在当前企业下的项目权限
                List<Project> projectByAccount = projectService.getProjectByAccount(organizationQuery.getEnterpriseId(), organizationQuery.getAccountId());
                List<Integer> collect = projectByAccount.stream().map(i -> i.getId()).collect(Collectors.toList());
                if(CollectionUtils.isEmpty(collect)){
                    log.warn("帐号没有关联项目数据");
                    return Collections.emptyList();
                }
                projectQueryWrapper.in("id", collect);
            }
        }

        projectQueryWrapper.eq("is_deleted", false);
        if(StringUtils.isNotEmpty(organizationQuery.getKeywords())){
            projectQueryWrapper.like("name", organizationQuery.getKeywords());
        }
        //不根据当前账号权限查询项目信息
        if(null != enterprise && null != organizationQuery.getEnterpriseId()){
            if (enterprise.getType().toString().contains(EnterpriseTypeEnum.OPERATOR.id.toString())){
                projectQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
            }else if (!organizationQuery.getIsAccountAuth()){
                QueryWrapper<EnterpriseProject> enterpriseProjectQueryWrapper = new QueryWrapper<>();
                enterpriseProjectQueryWrapper.eq("enterprise_id", organizationQuery.getEnterpriseId());
                List<EnterpriseProject> list2 = enterpriseProjectService.list(enterpriseProjectQueryWrapper);
                if(list2.isEmpty()){
                    return Collections.emptyList();
                }
                projectQueryWrapper.in("id", list2.stream().map(i -> i.getProjectId()).collect(Collectors.toList()));
            }
        }
        List<Project> list = projectService.list(projectQueryWrapper);
        // 过滤和角色项目级权限没有交集的项目
        if(CollectionUtils.isNotEmpty(organizationQuery.getRoleIds()) && CollectionUtils.isNotEmpty(list)){
            QueryWrapper<ProjectPermission> projectPermissionQueryWrapper = new QueryWrapper<>();
            projectPermissionQueryWrapper.in("project_id", list.stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<ProjectPermission> list1 = projectPermissionService.list(projectPermissionQueryWrapper);
            Map<Integer, List<Integer>> projectPermissionMap = list1.stream().collect(Collectors.groupingBy(ProjectPermission::getProjectId, Collectors.mapping(ProjectPermission::getPermissionId, Collectors.toList())));

            QueryWrapper<RolePermission> rolePermissionQueryWrapper = new QueryWrapper<>();
            rolePermissionQueryWrapper.in("role_id", organizationQuery.getRoleIds());
            List<RolePermission> list2 = rolePermissionService.list(rolePermissionQueryWrapper);
            List<Integer> permissions = list2.stream().map(i -> i.getPermissionId()).distinct().collect(Collectors.toList());
            // 其实不用再过滤项目级权限，项目只有项目级权限就可以取交集了，这里为了兼容旧数据
            QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
            if(permissions.isEmpty()){
                log.info("暂无权限信息");
                return Collections.emptyList();
            }
            permissionQueryWrapper.in("id", permissions);
            permissionQueryWrapper.eq("type", PermissionTypeEnum.PROJECT.type);
            List<Permission> list3 = permissionService.list(permissionQueryWrapper);
            if(list3.isEmpty()){
                log.info("角色暂无项目级权限");
                return Collections.emptyList();
            }
            List<Integer> collect = list3.stream().map(i -> i.getId()).collect(Collectors.toList());
            List<Integer> removeId = new ArrayList<>();
            for (Map.Entry<Integer, List<Integer>> entry : projectPermissionMap.entrySet()) {
                entry.getValue().retainAll(collect);
                if(entry.getValue().size() == 0){
                    removeId.add(entry.getKey());
                }
            }
            if(!removeId.isEmpty()){
                list = list.stream().filter(i -> !removeId.contains(i.getId())).collect(Collectors.toList());
            }
        }
        //获取用户上次推出时的项目
        Integer defaultProject = accountService.getById(account.getId()).getDefaultProject();
        //获取上次退出时的企业
        Integer defaultEnterprise = accountService.getById(account.getId()).getDefaultEnterprise();
        //获取项目业业态场景名称
        for (Project project : list) {
            Scene scene = sceneService.getById(project.getSceneId());
            if (null != scene){
                project.setSceneName(scene.getName());
            }
            if (null != defaultEnterprise && organizationQuery.getEnterpriseId().equals(defaultEnterprise) &&
                    null != defaultProject && project.getId().equals(defaultProject)){
                project.setSelectedItems(true);
            }
        }
        return list;
    }

    @Override
    public List<OrganizationTypeEnum> type(Short industryId) {
        return OrganizationTypeEnum.get(IndustryEnum.valueOfId(industryId));
    }

    /**
     * 通讯录组织查询
     *
     * @param organizationQuery
     * @return
     */
    @Override
    public List<OrganizationDTO> contactTree(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        // 结果要形成树必须包含当前结果的所有父级结点
        if (null != organizationQuery.getEnterpriseId()) {
            list = parent(list, organizationQuery);
        }
        if (null == organizationQuery.getRoundLevel()) {
            if (organizationQuery != null) {
                if (null != organizationQuery.getTypes() && !organizationQuery.getTypes().isEmpty()) {
                    list = list.stream().filter(o -> organizationQuery.getTypes().contains(o.getType())).collect(Collectors.toList());
                }
            }
        }
        list = visibleFilter(list, organizationQuery);
        return treeMaker(list);
    }

    @Override
    public List<Organization> contactList(OrganizationQuery organizationQuery) {
        List<Organization> list = list(organizationQuery);
        return visibleFilter(list, organizationQuery);
    }

    @Override
    public List<OrgStaffTreeDTO> editTree(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO) {
        if (null == orgStaffTreeQueryDTO.getEnterpriseId()) {
            throw new BusinessException("缺少企业id");
        }
        // 组织
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.setEnterpriseId(orgStaffTreeQueryDTO.getEnterpriseId());
        if (null != orgStaffTreeQueryDTO.getParentId()) {
            organizationQuery.setParentId(orgStaffTreeQueryDTO.getParentId());
        }
        if (StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords())) {
            organizationQuery.setKeywords(orgStaffTreeQueryDTO.getKeywords());
        }
        organizationQuery.setTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue()));
        List<Organization> list = list(organizationQuery);
        organizationQuery.setVisibleAccount(orgStaffTreeQueryDTO.getAccountId());
        list = visibleFilter(list, organizationQuery);
        // 帐号
//        List<Account> account = getAccount(orgStaffTreeQueryDTO);
        List<StaffDTO> staffDTOS = getStaff(orgStaffTreeQueryDTO);
        return toStaffTreeDTO(list, staffDTOS, orgStaffTreeQueryDTO.getParentId(), false);
    }

    @Override
    public List<OrgStaffTreeDTO> editTreeNoVisiable(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO) {
        if (null == orgStaffTreeQueryDTO.getEnterpriseId()) {
            throw new BusinessException("缺少企业id");
        }
        // 组织
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.setEnterpriseId(orgStaffTreeQueryDTO.getEnterpriseId());
        if (null != orgStaffTreeQueryDTO.getParentId()) {
            organizationQuery.setParentId(orgStaffTreeQueryDTO.getParentId());
        }
        organizationQuery.setTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue()));
        if (StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords())) {
            organizationQuery.setKeywords(orgStaffTreeQueryDTO.getKeywords());
            if (orgStaffTreeQueryDTO.getIsQueryUp()){
                organizationQuery.setRoundLevel(10);
            }
        }
        if (orgStaffTreeQueryDTO.getIsQueryUp()){
            //查询上级
            organizationQuery.setTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue(),OrganizationTypeEnum.ENTERPRISE.id.intValue()));
        }
        List<Organization> list = list(organizationQuery);
        // 帐号
//        List<Account> account = getAccount(orgStaffTreeQueryDTO);
        List<StaffDTO> staffDTOS = getStaff(orgStaffTreeQueryDTO);
        if (StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords()) && orgStaffTreeQueryDTO.getIsQueryUp()){
            organizationQuery = new OrganizationQuery();
            organizationQuery.setRoundLevel(10);
            organizationQuery.setIds(staffDTOS.stream().map(StaffDTO::getOrgIds).flatMap(Collection::stream).collect(Collectors.toList()));
            list.addAll(list(organizationQuery));
        }
        return toStaffTreeDTO(list, staffDTOS, orgStaffTreeQueryDTO.getParentId(),StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords()) && orgStaffTreeQueryDTO.getIsQueryUp());
    }

    @Override
    public OrganizationDTO detail(Integer id) {
        Organization byId = getById(id);
        OrganizationDTO organizationDTO = new OrganizationDTO();
        QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
        organizationManagerQueryWrapper.eq("org_id", byId.getId());
        List<OrganizationManager> list = organizationManagerService.list(organizationManagerQueryWrapper);
        BeanUtils.copyProperties(byId, organizationDTO);
        if (!list.isEmpty()) {
            organizationDTO.setManager(list);
        }
        return organizationDTO;
    }

    @Override
    public Organization detailByCodeAndType(String code, Integer type) {
        return organizationDao.selectOne(new QueryWrapper<Organization>().eq("code", code).eq("type", type));
    }

    @Override
    public ResultJson checkUniqueCode(OrganizationDTO dto) {
        return 0 == organizationDao.checkUniqueCode(dto) ? ResultJson.success() : ResultJson.fail("编码重复");
    }

    @Override
    public List<OrganizationDTO> listV2(OrganizationQuery query) {
        List<Organization> list = list(query);
        if(CollectionUtils.isEmpty(list)){
            return Collections.emptyList();
        }else{
            List<Integer> collect = list.stream().map(i -> i.getId()).collect(Collectors.toList());
            List<OrganizationDTO> list1 = new ArrayList<>(list.size());
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.select("id", "parent_id", "type");
            organizationQueryWrapper.in("parent_id", collect);
            organizationQueryWrapper.eq("is_deleted", false);
            organizationQueryWrapper.orderByAsc("if(sort_field is not null ,sort_field, 100000)","created_at");
            List<Organization> organizations = organizationDao.selectList(organizationQueryWrapper);
            // 组织的
            Map<Integer, Integer> idMap = organizations.stream().filter(i -> i.getType().equals(OrganizationTypeEnum.ORG.id.intValue())).collect(Collectors.toMap(Organization::getParentId, Organization::getId, (key1, key2) -> key2));
            // 全部下级的
            Map<Integer, Integer> allMap = organizations.stream().collect(Collectors.toMap(Organization::getParentId, Organization::getId, (key1, key2) -> key2));
            for (Organization organization : list) {
                OrganizationDTO organizationDTO = new OrganizationDTO();
                BeanUtils.copyProperties(organization, organizationDTO);
                organizationDTO.setHasOrgChild(idMap.get(organizationDTO.getId()) != null);
                organizationDTO.setHasChild(allMap.get(organizationDTO.getId()) != null);
                list1.add(organizationDTO);
            }
            return getOrganizationManager(list1);
        }
    }

    @Override
    public ResultJson allToTree(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO) {
        if (null == orgStaffTreeQueryDTO.getEnterpriseId()) {
            throw new BusinessException("缺少企业id");
        }
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.setEnterpriseId(orgStaffTreeQueryDTO.getEnterpriseId());
        if (null != orgStaffTreeQueryDTO.getParentId()) {
            organizationQuery.setParentId(orgStaffTreeQueryDTO.getParentId());
        }
        if (StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords())) {
            organizationQuery.setKeywords(orgStaffTreeQueryDTO.getKeywords());
        }
        organizationQuery.setTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue()));
        List<Organization> list = list(organizationQuery);
        List<Account> accounts = getAccount(orgStaffTreeQueryDTO);
        return ResultJson.success(allToStaffTreeDTO(list,accounts,orgStaffTreeQueryDTO.getParentId()));
    }

    @Override
    public List<OrganizationDTO> getOrgByEntId() {
        List<OrganizationDTO> result = new ArrayList<>();
        //获得所有企业
        QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
        entQueryWrapper.in("is_deleted", 0);
        List<Enterprise> ents = enterpriseDao.selectList(entQueryWrapper);
        //获得企业下的组织
        for(Enterprise vo:ents){
            //todo 测试使用
            /*if(vo.getId()!=744){
                continue;
            }*/
            //获取企业组织
            Organization organization = organizationDao.selectById(vo.getOrganizationId());
            OrganizationDTO organizationDTO = new OrganizationDTO();
            BeanUtils.copyProperties(organization, organizationDTO);
            //获取组织树
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.setEnterpriseId(vo.getId());
            organizationQuery.setTypes(Arrays.asList(OrganizationTypeEnum.ORG.id.intValue()));
            List<OrganizationDTO> organizationDTOS = treeWithManager(organizationQuery);
            if(CollectionUtils.isEmpty(organizationDTOS)){
                continue;
            }
            organizationDTO.setChildren(organizationDTOS);
            organizationDTO.setHasChild(true);
            result.add(organizationDTO);
        }
        return result;
    }

    @Override
    public List<OrganizationDTO> allSpace() {
        List<OrganizationDTO> result = new ArrayList<>();
        //获得运营商企业
        QueryWrapper<Enterprise> entQueryWrapper = new QueryWrapper<>();
        entQueryWrapper.in("is_deleted", 0);
        entQueryWrapper.in("type", 1);
        List<Enterprise> ents = enterpriseDao.selectList(entQueryWrapper);
        //获得企业下的组织
        for(Enterprise vo:ents){
            //获取企业组织
            Organization organization = organizationDao.selectById(vo.getOrganizationId());
            OrganizationDTO organizationDTO = new OrganizationDTO();
            BeanUtils.copyProperties(organization, organizationDTO);
            //获取组织树
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.setEnterpriseId(vo.getId());
            //获得类型组织之外的类型
            QueryWrapper<OrganizationType> typeWrapper = new QueryWrapper<>();
            typeWrapper.ne("id", 4);
            List<OrganizationType> organizationTypes = organizationTypeDao.selectList(typeWrapper);
            List<Integer> collect = organizationTypes.stream().map(i -> i.getId()).collect(Collectors.toList());
            organizationQuery.setTypes(collect);
            //获得树
            List<OrganizationDTO> organizationDTOS = treeWithManager(organizationQuery);
            if(CollectionUtils.isEmpty(organizationDTOS)){
                continue;
            }
            organizationDTO.setChildren(organizationDTOS);
            organizationDTO.setHasChild(true);
            result.add(organizationDTO);
        }
        return result;
    }

    @Override
    public Map<Integer, List<Organization>> getParent(OrganizationQuery query) {
        QueryWrapper<Organization> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("id","name","parent_id","type","level","enterprise_id","project_id");
        queryWrapper.in("id",query.ids);
        List<Organization> organizationList = this.list(queryWrapper);
        if (CollectionUtils.isEmpty(organizationList)){
            return null;
        }
        Organization organization = organizationList.get(0);
        QueryWrapper<Organization> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.select("id","name","parent_id","type","level");
        queryWrapper1.lt("level",organization.getLevel());
        queryWrapper1.eq("enterprise_id",organization.getEnterpriseId());
        queryWrapper1.eq("project_id",organization.getProjectId());
        List<Organization> base = this.list(queryWrapper1);
        Map<Integer,List<Organization>> result = new HashMap<>();
        for (Organization o : organizationList){
            List<Organization> organizations= new ArrayList<>();
            organizations.add(o);
            List<Organization> parent = getParents(new ArrayList<>(), base, organizations);
            if (CollectionUtils.isNotEmpty(parent)){
                if (null != query.getTypes()){
                    parent = parent.stream().filter(i -> query.getTypes().contains(i.getType())).collect(Collectors.toList());
                }
            }
            result.put(o.getId(),parent);
        }
        return result;
    }


    private List<Account> getAccount(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO) {
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.eq("enterprise_id", orgStaffTreeQueryDTO.getEnterpriseId());
        if (null != orgStaffTreeQueryDTO.getParentId()) {
            staffOrganizationQueryWrapper.eq("org_id", orgStaffTreeQueryDTO.getParentId());
        }
        List<StaffOrganization> staffOrganizations = staffOrganizationDao.selectList(staffOrganizationQueryWrapper);
        List<Integer> collect = staffOrganizations.stream().map(i -> i.getAccountId()).collect(Collectors.toList());
        List<Account> list2 = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(collect)) {
            QueryWrapper<Account> accountQueryWrapper = new QueryWrapper<>();
            if (StringUtils.isNotEmpty(orgStaffTreeQueryDTO.getKeywords())) {
                accountQueryWrapper.like("name", orgStaffTreeQueryDTO.getKeywords());
            }
            accountQueryWrapper.select("id", "name","login_name");
            accountQueryWrapper.in("id", collect);
            list2 = accountService.list(accountQueryWrapper);
        }
        return list2;
    }

    private List<StaffDTO> getStaff(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO){
        StaffQuery staffQuery = new StaffQuery();
        staffQuery.setEnterpriseId(orgStaffTreeQueryDTO.getEnterpriseId());
        if (null != orgStaffTreeQueryDTO.getParentId()) {
            staffQuery.setOrgId(orgStaffTreeQueryDTO.getParentId());
        }
        if (null != orgStaffTreeQueryDTO.getKeywords()){
            staffQuery.setKeywords(orgStaffTreeQueryDTO.getKeywords());
        }
        if (orgStaffTreeQueryDTO.getExcludeEntManager()){
            Integer entId = orgStaffTreeQueryDTO.getEnterpriseId();
            Map<Integer, Account> accountMap = enterpriseService.findEnterpriseAdmin(Collections.singletonList(entId));
            staffQuery.setExcludeAccountIds(Collections.singletonList(accountMap.get(entId).getId()));
        }
        staffQuery.setShowCurrent(true);
        return staffService.list(staffQuery);
    }

    /**
     * 转成 既能包含组织 也能包含帐号的对象返回
     *
     * @return
     */
    private List<OrgStaffTreeDTO> toStaffTreeDTO(List<Organization> organizations, List<StaffDTO> staffDTOS, Integer parentId, Boolean isQueryUp) {

        List<OrgStaffTreeDTO> orgStaffTreeDTOS = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(organizations)) {

            List<Integer> ids = organizations.stream().map(i -> i.getId()).collect(Collectors.toList());
            QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
            organizationQueryWrapper.select("parent_id").groupBy("parent_id").having("count(id) > 0");
            organizationQueryWrapper.in("parent_id", ids);
            organizationQueryWrapper.eq("type", OrganizationTypeEnum.ORG.id);
            List<Object> objects = this.listObjs(organizationQueryWrapper);
            Set<Integer> hasChilds = new HashSet<>();
            if (!CollectionUtils.isEmpty(objects)) {
                hasChilds = objects.stream().map(i -> Integer.valueOf(i.toString())).collect(Collectors.toSet());
            }
            // 组织下面有员工的 hasChild也是true
            QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
            staffOrganizationQueryWrapper.select("id", "org_id");
            staffOrganizationQueryWrapper.in("org_id", ids);
            List<StaffOrganization> staffOrganizations = staffOrganizationDao.selectList(staffOrganizationQueryWrapper);

            if (CollectionUtils.isNotEmpty(staffOrganizations)) {
                Set<Integer> collect = staffOrganizations.stream().map(i -> i.getOrgId()).collect(Collectors.toSet());
                hasChilds.addAll(collect);
            }

            for (Organization organization : organizations) {
                OrgStaffTreeDTO orgStaffTreeDTO = new OrgStaffTreeDTO();
                orgStaffTreeDTO.setId("o_" + organization.getId());
                orgStaffTreeDTO.setName(organization.getName());
                orgStaffTreeDTO.setRelationId(organization.getId());
                orgStaffTreeDTO.setParentId("o_" + organization.getParentId());
                orgStaffTreeDTO.setType((short) 0);
                List<Organization> organizationList= new ArrayList<>();
                organizationList.add(organization);
                List<Organization> parentOrg = parent(organizationList,new OrganizationQuery().withEnterpriseId(organization.getEnterpriseId()));
                parentOrg.add(organization);
                orgStaffTreeDTO.setOrgIds(parentOrg.stream().distinct().map(Organization::getId).collect(Collectors.toList()));
                if (hasChilds.contains(organization.getId())) {
                    orgStaffTreeDTO.setHasChild(true);
                }
                orgStaffTreeDTOS.add(orgStaffTreeDTO);
            }
        }
        if (CollectionUtils.isNotEmpty(staffDTOS)) {
            if (isQueryUp){
                for (StaffDTO staffDTO : staffDTOS) {
                    for (Integer integer : staffDTO.getOrgIds()){
                        OrgStaffTreeDTO orgStaffTreeDTO = new OrgStaffTreeDTO();
                        orgStaffTreeDTO.setId("a_" + staffDTO.getAccountId());
                        orgStaffTreeDTO.setName(staffDTO.getName());
                        orgStaffTreeDTO.setLoginName(staffDTO.getLoginName());
                        orgStaffTreeDTO.setRelationId(staffDTO.getAccountId());
                        orgStaffTreeDTO.setType((short) 1);
                        orgStaffTreeDTO.setStaffId(staffDTO.getId());
                        orgStaffTreeDTO.setOrgIds(staffDTO.getOrgIds());
                        orgStaffTreeDTO.setPhone(staffDTO.getPhone());
                        orgStaffTreeDTO.setParentId("o_" + integer);
                        orgStaffTreeDTOS.add(orgStaffTreeDTO);
                    }
                }
            }else {
                for (StaffDTO staffDTO : staffDTOS) {
                    OrgStaffTreeDTO orgStaffTreeDTO = new OrgStaffTreeDTO();
                    orgStaffTreeDTO.setId("a_" + staffDTO.getAccountId());
                    orgStaffTreeDTO.setName(staffDTO.getName());
                    orgStaffTreeDTO.setLoginName(staffDTO.getLoginName());
                    orgStaffTreeDTO.setRelationId(staffDTO.getAccountId());
                    orgStaffTreeDTO.setParentId("o_" + parentId);
                    orgStaffTreeDTO.setType((short) 1);
                    orgStaffTreeDTO.setStaffId(staffDTO.getId());
                    if(staffDTO != null && CollectionUtils.isNotEmpty(staffDTO.getParentOrgs())) {
                        staffDTO.getOrgIds().addAll(staffDTO.getParentOrgs().stream().map(Organization::getId).collect(Collectors.toList()));
                    }
                    if(staffDTO != null && CollectionUtils.isNotEmpty(staffDTO.getOrgIds())) {
                        orgStaffTreeDTO.setOrgIds(staffDTO.getOrgIds().stream().distinct().collect(Collectors.toList()));
                    }
                    orgStaffTreeDTO.setPhone(staffDTO.getPhone());
                    orgStaffTreeDTOS.add(orgStaffTreeDTO);
                }
            }
        }
        return orgStaffTreeDTOS;
    }


    private List<OrgStaffTreeDTO> allToStaffTreeDTO(List<Organization> organizations, List<Account> accounts,Integer parent){
        List<OrgStaffTreeDTO> orgStaffTreeDTOS = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(organizations)) {
            Map<Integer,List<Organization>> orgMap = organizations.stream().collect(Collectors.groupingBy(Organization::getParentId));
            Optional<Organization> optionalOrganization = organizations.stream().min(Comparator.comparingInt(Organization::getLevel));
            //组织最高层级
            Integer maxLevel = optionalOrganization.get().getLevel();
            List<Integer> ids = organizations.stream().map(i -> i.getId()).collect(Collectors.toList());
            //组织下的人员
            QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
            staffOrganizationQueryWrapper.select("account_id", "org_id");
            staffOrganizationQueryWrapper.in("org_id", ids);
            List<StaffOrganization> staffOrganizations = staffOrganizationDao.selectList(staffOrganizationQueryWrapper);
            Map<Integer, List<StaffOrganization>> staffOrgMap = staffOrganizations.stream().collect(Collectors.groupingBy(StaffOrganization ::getOrgId));
            Map<Integer,List<Account>> accountMap = new HashMap<>();
            List<Integer> accountId = new ArrayList<>();
            List<String> firstLevel = new ArrayList<>();
            for (Map.Entry<Integer, List<StaffOrganization>> map : staffOrgMap.entrySet()){
                List<Integer> accountIds = map.getValue().stream().map(StaffOrganization::getAccountId).collect(Collectors.toList());
                List<Account> accounts1 = accounts.stream().filter(i -> accountIds.contains(i.getId())).collect(Collectors.toList());
                accountId.addAll(accountIds);
                accountMap.put(map.getKey(),accounts1);
            }
            //过滤出根节点下的人员
            accounts = accounts.stream().filter(i -> !accountId.contains(i.getId())).collect(Collectors.toList());
            //处理子节点
            for (Organization organization : organizations) {
                OrgStaffTreeDTO orgStaffTreeDTO = new OrgStaffTreeDTO();
                orgStaffTreeDTO.setId("o_" + organization.getId());
                orgStaffTreeDTO.setName(organization.getName());
                orgStaffTreeDTO.setRelationId(organization.getId());
                orgStaffTreeDTO.setParentId("o_" + organization.getParentId());
                orgStaffTreeDTO.setType((short) 0);
                //
                List<OrgStaffTreeDTO> children = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(accountMap.get(organization.getId()))){
                    for (Account account : accountMap.get(organization.getId())){
                        OrgStaffTreeDTO staffTreeDTO = new OrgStaffTreeDTO();
                        staffTreeDTO.setId("a_" + account.getId());
                        staffTreeDTO.setName(account.getName());
                        staffTreeDTO.setLoginName(account.getLoginName());
                        staffTreeDTO.setRelationId(account.getId());
                        staffTreeDTO.setParentId("o_" + organization.getId());
                        staffTreeDTO.setType((short) 1);
                        children.add(staffTreeDTO);
                    }
                    orgStaffTreeDTO.setHasChild(true);
                }
                if (CollectionUtils.isNotEmpty(orgMap.get(organization.getId()))){
                    for (Organization organization1 : orgMap.get(organization.getId())){
                        OrgStaffTreeDTO orgTree = new OrgStaffTreeDTO();
                        orgTree.setId("o_" + organization1.getId());
                        orgTree.setName(organization1.getName());
                        orgTree.setRelationId(organization1.getId());
                        orgTree.setParentId("o_" + organization.getId());
                        orgTree.setType((short) 0);
                        children.add(orgTree);
                    }
                    orgStaffTreeDTO.setHasChild(true);
                }
                orgStaffTreeDTO.setChildren(children);
                orgStaffTreeDTOS.add(orgStaffTreeDTO);
                if (maxLevel.equals(organization.getLevel())){
                    firstLevel.add(orgStaffTreeDTO.getId());
                }
            }
            //处理父节点
            Map<String,List<OrgStaffTreeDTO>> orgStaffTreeMap = orgStaffTreeDTOS.stream().collect(Collectors.groupingBy(OrgStaffTreeDTO::getParentId));
            for (OrgStaffTreeDTO orgStaffTreeDTO : orgStaffTreeDTOS){
                if (null != orgStaffTreeMap.get(orgStaffTreeDTO.getId())){
                    orgStaffTreeDTO.setChildren(orgStaffTreeMap.get(orgStaffTreeDTO.getId()));
                }
            }
            //过滤最高层的节点
            orgStaffTreeDTOS = orgStaffTreeDTOS.stream().filter(i -> firstLevel.contains(i.getId())).collect(Collectors.toList());
        }
        //处理根节点的人员
        if (CollectionUtils.isNotEmpty(accounts)){
            for (Account account : accounts){
                OrgStaffTreeDTO staffTreeDTO = new OrgStaffTreeDTO();
                staffTreeDTO.setId("a_" + account.getId());
                staffTreeDTO.setName(account.getName());
                staffTreeDTO.setLoginName(account.getLoginName());
                staffTreeDTO.setRelationId(account.getId());
                staffTreeDTO.setParentId("o_" + parent);
                staffTreeDTO.setType((short) 1);
                orgStaffTreeDTOS.add(staffTreeDTO);
            }
        }
        return orgStaffTreeDTOS;
    }
    /**
     * 组织可见性过滤
     *
     * @param list
     * @param organizationQuery
     * @return
     */
    private List<Organization> visibleFilter(List<Organization> list, OrganizationQuery organizationQuery) {

        if (list.isEmpty()) {
            return list;
        }
        Integer accountId = organizationQuery.getVisibleAccount();
        if (roleService.isSuperManager(accountId)) {
            return list;
        }
        QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
        staffOrganizationQueryWrapper.select("org_id", "enterprise_id");
        staffOrganizationQueryWrapper.eq("account_id", accountId);
        List<StaffOrganization> staffOrganizations = staffOrganizationDao.selectList(staffOrganizationQueryWrapper);
        List<Integer> accountOrganizationIds = staffOrganizations.stream().map(i -> i.getOrgId()).distinct().collect(Collectors.toList());

        List<Integer> relationOrgId = getParent(accountOrganizationIds, staffOrganizations.get(0).getEnterpriseId());

        // 不可见的组织 但是与当前组织相关的不会隐藏
        List<Organization> hiddens = list.stream().filter(i -> OrganizationViewStatusEnum.HIDDEN.code == i.getViewStatus()).collect(Collectors.toList());
        if (!hiddens.isEmpty()) {
            List<Organization> needTORemove = new ArrayList<>();
            for (Organization hidden : hiddens) {
                if (!relationOrgId.contains(hidden.getId())) {
                    needTORemove.add(hidden);
                }
            }
            list.removeAll(needTORemove);
        }
        // 部分可见的组织
        List<Organization> limitOrganization = list.stream().filter(i -> OrganizationViewStatusEnum.LIMITED_ACCESS.code == i.getViewStatus()).collect(Collectors.toList());
        if (!limitOrganization.isEmpty()) {

            QueryWrapper<OrganizationVisibility> organizationVisibilityQueryWrapper = new QueryWrapper<>();
            organizationVisibilityQueryWrapper.in("org_id", limitOrganization.stream().map(i -> i.getId()).collect(Collectors.toList()));
            List<OrganizationVisibility> list1 = organizationVisibilityService.list(organizationVisibilityQueryWrapper);

            if (list1.isEmpty()) {
                list.removeAll(limitOrganization);
                return list;
            }
            List<Integer> cannotSee = new ArrayList<>();
            // 遍历部分可见的组织 过滤掉当前帐号不可见的


            List<Integer> canSee = new ArrayList<>();
            List<OrganizationVisibility> accountSee = list1.stream().filter(i -> i.getObjectType().equals(OrganizationVisibleObjectTypeEnum.ACCOUNT.code)).collect(Collectors.toList());
            // 帐号处理
            if (!accountSee.isEmpty()) {
                // 当前帐号能看的组织
                List<Integer> collect = accountSee.stream().filter(i -> i.getRelationId().equals(accountId)).map(j -> j.getOrgId()).collect(Collectors.toList());
                canSee.addAll(collect);
            }
            // 组织处理
            List<OrganizationVisibility> collect3 = list1.stream().filter(i -> i.getObjectType().equals(OrganizationVisibleObjectTypeEnum.ORG.code)).collect(Collectors.toList());
            if (!collect3.isEmpty()) {
                // 当前帐号能看的组织
                List<Integer> collect4 = collect3.stream().filter(i -> accountOrganizationIds.contains(i.getRelationId())).map(i -> i.getOrgId()).collect(Collectors.toList());
                canSee.addAll(collect4);
            }
            if (canSee.isEmpty()) {
                List<Integer> collect = list1.stream().map(i -> i.getOrgId()).collect(Collectors.toList());
                list = list.stream().filter(i -> !collect.contains(i.getId())).collect(Collectors.toList());
            } else {
                // 限制里面不可见的
                List<Integer> collect = list1.stream().map(i -> i.getOrgId()).filter(i -> !canSee.contains(i)).collect(Collectors.toList());
                list = list.stream().filter(i -> !collect.contains(i.getId())).collect(Collectors.toList());
            }
        }
        return list;
    }

    private List<Integer> getParent(List<Integer> accountOrganizationIds, Integer enterpriseId) {

        if (CollectionUtils.isEmpty(accountOrganizationIds)) {
            return Collections.emptyList();
        }
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.setEnterpriseId(enterpriseId);
        List<Organization> enterpriseAll = list(organizationQuery);

        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.select("id", "name", "parent_id", "level");
        organizationQueryWrapper.in("id", accountOrganizationIds);
        List<Organization> curr = list(organizationQueryWrapper);

        Map<Integer, Organization> allMap = enterpriseAll.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key1));
        Map<Integer, Organization> baseMap = curr.stream().collect(Collectors.toMap(Organization::getId, Function.identity(), (key1, key2) -> key1));
        return getParent(baseMap, allMap).stream().map(i -> i.getId()).collect(Collectors.toList());
    }

    /**
     * 根据项目集合查询项目对应的组织信息
     *
     * @param projects
     * @return map key-projectId value-organizationTree
     */
    private Map<Integer, List<Organization>> getDefaultTypeOrganization(List<Organization> projects) {
        List<Integer> enterpriseIds = projects.stream().map(p -> p.getEnterpriseId()).distinct().collect(Collectors.toList());
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper.in("enterprise_id", enterpriseIds);
        organizationQueryWrapper.eq("type", OrganizationTypeEnum.ORG);
        List<Organization> defaultOrganizations = organizationDao.selectList(organizationQueryWrapper);
        Map<Integer, List<Organization>> map = new HashMap<>();
        for (Organization organization : projects) {
            List<Organization> parents = new ArrayList<>();
            listParentsByOrganization(parents, defaultOrganizations, Arrays.asList(organization));
            map.put(organization.getId(), parents);
        }
        return map;
    }

    public void organizationLogRecord(Account operateAccount, LogOperationTypeEnum logOperationTypeEnum, String operateContent, Organization organization) {
        OperateLog operateLog = new OperateLog();
        operateLog.setMenu(ModuleTypeEnum.ORGANIZATION_MANAGE.getName());
        operateLog.setOperateType(logOperationTypeEnum.getType());
        operateLog.setOperateContent(operateContent);
        operateLog.setEnterpriseId(organization.getEnterpriseId());
        operateLog.setProjectId(organization.getProjectId());
        operateLog.setIp(ThreadLocalUtil.getIp());
        operateLog.setIndustryId(ThreadLocalUtil.getIndustryId());
        if (null == operateAccount) {
            operateAccount = ThreadLocalUtil.getAccount();
        }
        if (null != operateAccount) {
            operateLog.setIndustryId(operateAccount.getIndustryId());
            operateLog.setAccountId(operateAccount.getId());
            operateLog.setLoginName(operateAccount.getLoginName());
            operateLog.setName(operateAccount.getName());
            //填充企业ids+项目ids
            List<Enterprise> enterprises = enterpriseService.list(null,operateAccount);
            if (!org.springframework.util.CollectionUtils.isEmpty(enterprises)){
                operateLog.setEnterpriseIds(enterprises.stream().map(Enterprise::getId).collect(Collectors.toList()));
            }
            List<AccountDetailDTO> projectInfoList = accountService.getAccountProjectInfoByIdList(Collections.singletonList(operateAccount.getId()));
            operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            if (!org.springframework.util.CollectionUtils.isEmpty(projectInfoList)){
                operateLog.setProjectIds(projectInfoList.stream().map(AccountDetailDTO::getProjectId).collect(Collectors.toList()));
            }
        }
        logTemplate.addOperateLog(operateLog);

    }
}
